xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: xen-devel@lists.xen.org
Cc: edgar.iglesias@xilinx.com, julien.grall@arm.com, sstabellini@kernel.org
Subject: [RFC v2 5/6] xen/arm: zynqmp: Forward plaform specific firmware calls
Date: Tue,  7 Feb 2017 20:42:04 +0100	[thread overview]
Message-ID: <1486496525-14637-6-git-send-email-edgar.iglesias@gmail.com> (raw)
In-Reply-To: <1486496525-14637-1-git-send-email-edgar.iglesias@gmail.com>

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Implement an EEMI mediator and forward platform specific
firmware calls from guests to firmware.

The EEMI mediator is responsible for implementing access
controls modifying or blocking calls that try to operate
on setup for devices that are not under the calling guest's
control.

EEMI:
https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
---
 xen/arch/arm/platforms/Makefile                    |   1 +
 xen/arch/arm/platforms/xilinx-zynqmp-eemi.c        | 794 +++++++++++++++++++++
 xen/arch/arm/platforms/xilinx-zynqmp.c             |  18 +
 xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 337 +++++++++
 xen/include/asm-arm/platforms/xilinx-zynqmp-mm.h   | 284 ++++++++
 5 files changed, 1434 insertions(+)
 create mode 100644 xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
 create mode 100644 xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h
 create mode 100644 xen/include/asm-arm/platforms/xilinx-zynqmp-mm.h

diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile
index 49fa683..b58b71f 100644
--- a/xen/arch/arm/platforms/Makefile
+++ b/xen/arch/arm/platforms/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_ARM_64) += seattle.o
 obj-$(CONFIG_ARM_32) += sunxi.o
 obj-$(CONFIG_ARM_64) += xgene-storm.o
 obj-$(CONFIG_ARM_64) += xilinx-zynqmp.o
+obj-$(CONFIG_ARM_64) += xilinx-zynqmp-eemi.o
diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
new file mode 100644
index 0000000..c2c184d
--- /dev/null
+++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
@@ -0,0 +1,794 @@
+/*
+ * xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
+ *
+ * Xilinx ZynqMP EEMI API mediator.
+ *
+ * Copyright (c) 2017 Xilinx Inc.
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.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.
+ */
+
+/*
+ * Mediator for the EEMI Power Mangement API.
+ *
+ * Refs:
+ * https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf
+ *
+ * Background:
+ * The ZynqMP has a subsystem named the PMU with a CPU and special devices
+ * dedicated to running Power Management Firmware. Other masters in the
+ * system need to send requests to the PMU in order to for example:
+ * * Manage power state
+ * * Configure clocks
+ * * Program bitstreams for the programmable logic
+ * * etc
+ *
+ * Allthough the details of the setup are configurable, in the common case
+ * the PMU lives in the Secure world. NS World cannot directly communicate
+ * with it and must use proxy services from ARM Trusted Firmware to reach
+ * the PMU.
+ *
+ * Power Management on the ZynqMP is implemented in a layered manner.
+ * The PMU knows about various masters and will enforce access controls
+ * based on a pre-configured partitioning. This configuration dictates
+ * which devices are owned by the various masters and the PMU FW makes sure
+ * that a given master cannot turn off a device that it does not own or that
+ * is in use by other masters.
+ *
+ * The PMU is not aware of multiple execution states in masters.
+ * For example, it treats the ARMv8 cores as single units and does not
+ * distinguish between Secure vs NS OS:s nor does it know about Hypervisors
+ * and multiple guests. It is up to software on the ARMv8 cores to present
+ * a unified view of its power requirements.
+ *
+ * To implement this unified view, ARM Trusted Firmware at EL3 provides
+ * access to the PM API via SMC calls. ARM Trusted Firmware is responsible
+ * for mediating between the Secure and the NS world, rejecting SMC calls
+ * that request changes that are not allowed.
+ *
+ * Xen running above ATF owns the NS world and is responsible for presenting
+ * unified PM requests taking all guests and the hypervisor into account.
+ *
+ * Implementation:
+ * The PM API contains different classes of calls.
+ * Certain calls are harmless to expose to any guest.
+ * These include calls to get the PM API Version, or to read out the version
+ * of the chip we're running on.
+ *
+ * Other calls are more problematic. Here're some:
+ * * Power requests for nodes (i.e turn on or off a given device)
+ * * Reset line control (i.e reset a given device)
+ * * MMIO access (i.e directly access clock and reset registers)
+ *
+ * Power requests for nodes:
+ * In order to correctly mediate these calls, we need to know if
+ * guests issuing these calls have ownership of the given device.
+ * The approach taken here is to map PM API Nodes identifying
+ * a device into base addresses for registers that belong to that
+ * same device.
+ *
+ * If the guest has access to a devices registers, we give the guest
+ * access to PM API calls that affect that device. This is implemented
+ * by pm_node_access and domain_has_node_access().
+ *
+ * Reset lines:
+ * Reset lines are identified by a list of identifiers that do not relate
+ * to device nodes. We can use the same approach here as for nodes, except
+ * that we need a separate table mapping reset lines to base addresses.
+ * This is implemented by pm_reset_access.
+ *
+ * MMIO access:
+ * These calls allow guests to access certain memory ranges. These ranges
+ * are typically protected for secure-world access only and also from
+ * certain masters only, so guests cannot access them directly.
+ * Registers within the memory regions affect certain nodes. In this case,
+ * our imput is an address and we map that address into a node. If the
+ * guest has ownership of that node, the access is allowed.
+ * Some registers contain bitfields and a single register may contain
+ * bits that affect multiple nodes.
+ *
+ * Some of the calls act on more global state. For example acting on
+ * NODE_PS, which affects many a lot of nodes. This higher level
+ * orchestrating is left for the hardware-domain only.
+ */
+
+#include <xen/iocap.h>
+#include <asm/platform.h>
+#include <asm/platforms/xilinx-zynqmp-eemi.h>
+#include <asm/platforms/xilinx-zynqmp-mm.h>
+
+struct pm_access
+{
+    uint64_t addr;
+    bool hwdom_access;    /* HW domain gets access regardless.  */
+};
+
+/*
+ * This table maps a node into a memory address.
+ * If a guest has access to the address, it has enough control
+ * over the node to grant it access to EEMI calls for that node.
+ */
+static const struct pm_access pm_node_access[] = {
+    /* MM_RPU grants access to alll RPU Nodes.  */
+    [NODE_RPU] = { MM_RPU },
+    [NODE_RPU_0] = { MM_RPU },
+    [NODE_RPU_1] = { MM_RPU },
+    [NODE_IPI_RPU_0] = { MM_RPU },
+
+    /* GPU nodes.  */
+    [NODE_GPU] = { MM_GPU },
+    [NODE_GPU_PP_0] = { MM_GPU },
+    [NODE_GPU_PP_1] = { MM_GPU },
+
+    [NODE_USB_0] = { MM_USB3_0 },
+    [NODE_USB_1] = { MM_USB3_1 },
+    [NODE_TTC_0] = { MM_TTC0 },
+    [NODE_TTC_1] = { MM_TTC1 },
+    [NODE_TTC_2] = { MM_TTC2 },
+    [NODE_TTC_3] = { MM_TTC3 },
+    [NODE_SATA] = { MM_SATA_AHCI_HBA },
+    [NODE_ETH_0] = { MM_GEM0 },
+    [NODE_ETH_1] = { MM_GEM1 },
+    [NODE_ETH_2] = { MM_GEM2 },
+    [NODE_ETH_3] = { MM_GEM3 },
+    [NODE_UART_0] = { MM_UART0 },
+    [NODE_UART_1] = { MM_UART1 },
+    [NODE_SPI_0] = { MM_SPI0 },
+    [NODE_SPI_1] = { MM_SPI1 },
+    [NODE_I2C_0] = { MM_I2C0 },
+    [NODE_I2C_1] = { MM_I2C1 },
+    [NODE_SD_0] = { MM_SD0 },
+    [NODE_SD_1] = { MM_SD1 },
+    [NODE_DP] = { MM_DP },
+
+    /* Guest with GDMA Channel 0 gets PM access. Other guests don't.  */
+    [NODE_GDMA] = { MM_GDMA_CH0 },
+    /* Guest with ADMA Channel 0 gets PM access. Other guests don't.  */
+    [NODE_ADMA] = { MM_ADMA_CH0 },
+
+    [NODE_NAND] = { MM_NAND },
+    [NODE_QSPI] = { MM_QSPI },
+    [NODE_GPIO] = { MM_GPIO },
+    [NODE_CAN_0] = { MM_CAN0 },
+    [NODE_CAN_1] = { MM_CAN1 },
+
+    /* Dom0 only.  */
+    [NODE_AFI] = { .hwdom_access = true },
+    [NODE_APLL] = { .hwdom_access = true },
+    [NODE_VPLL] = { .hwdom_access = true },
+    [NODE_DPLL] = { .hwdom_access = true },
+    [NODE_RPLL] = { .hwdom_access = true },
+    [NODE_IOPLL] = { .hwdom_access = true },
+    [NODE_DDR] = { .hwdom_access = true },
+    [NODE_IPI_APU] = { .hwdom_access = true },
+    [NODE_PCAP] = { .hwdom_access = true },
+
+    [NODE_PCIE] = { MM_PCIE_ATTRIB },
+    [NODE_RTC] = { MM_RTC },
+};
+
+/*
+ * This table maps reset line IDs into a memory address.
+ * If a guest has access to the address, it has enough control
+ * over the affected node to grant it access to EEMI calls for
+ * resetting that node.
+ */
+#define PM_RESET_IDX(n) (n - PM_RESET_PCIE_CFG)
+static const struct pm_access pm_reset_access[] = {
+    [PM_RESET_IDX(PM_RESET_PCIE_CFG)] = { MM_AXIPCIE_MAIN },
+    [PM_RESET_IDX(PM_RESET_PCIE_BRIDGE)] = { MM_PCIE_ATTRIB },
+    [PM_RESET_IDX(PM_RESET_PCIE_CTRL)] = { MM_PCIE_ATTRIB },
+
+    [PM_RESET_IDX(PM_RESET_DP)] = { MM_DP },
+    [PM_RESET_IDX(PM_RESET_SWDT_CRF)] = { MM_SWDT },
+    [PM_RESET_IDX(PM_RESET_AFI_FM5)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM4)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM3)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM2)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM1)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM0)] = { .hwdom_access = true },
+
+    /* Channel 0 grants PM access.  */
+    [PM_RESET_IDX(PM_RESET_GDMA)] = { MM_GDMA_CH0 },
+    [PM_RESET_IDX(PM_RESET_GPU_PP1)] = { MM_GPU },
+    [PM_RESET_IDX(PM_RESET_GPU_PP0)] = { MM_GPU },
+    [PM_RESET_IDX(PM_RESET_GT)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_SATA)] = { MM_SATA_AHCI_HBA },
+
+    /* We don't allow anyone to turn on/off the ACPUs.  */
+    [PM_RESET_IDX(PM_RESET_ACPU3_PWRON)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU2_PWRON)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU1_PWRON)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU0_PWRON)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_APU_L2)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU3)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU2)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU1)] = { 0 },
+    [PM_RESET_IDX(PM_RESET_ACPU0)] = { 0 },
+
+    [PM_RESET_IDX(PM_RESET_DDR)] = { 0 },
+
+    [PM_RESET_IDX(PM_RESET_APM_FPD)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_SOFT)] = { .hwdom_access = true },
+
+    [PM_RESET_IDX(PM_RESET_GEM0)] = { MM_GEM0 },
+    [PM_RESET_IDX(PM_RESET_GEM1)] = { MM_GEM1 },
+    [PM_RESET_IDX(PM_RESET_GEM2)] = { MM_GEM2 },
+    [PM_RESET_IDX(PM_RESET_GEM3)] = { MM_GEM3 },
+
+    [PM_RESET_IDX(PM_RESET_QSPI)] = { MM_QSPI },
+    [PM_RESET_IDX(PM_RESET_UART0)] = { MM_UART0 },
+    [PM_RESET_IDX(PM_RESET_UART1)] = { MM_UART1 },
+    [PM_RESET_IDX(PM_RESET_SPI0)] = { MM_SPI0 },
+    [PM_RESET_IDX(PM_RESET_SPI1)] = { MM_SPI1 },
+    [PM_RESET_IDX(PM_RESET_SDIO0)] = { MM_SD0 },
+    [PM_RESET_IDX(PM_RESET_SDIO1)] = { MM_SD1 },
+    [PM_RESET_IDX(PM_RESET_CAN0)] = { MM_CAN0 },
+    [PM_RESET_IDX(PM_RESET_CAN1)] = { MM_CAN1 },
+    [PM_RESET_IDX(PM_RESET_I2C0)] = { MM_I2C0 },
+    [PM_RESET_IDX(PM_RESET_I2C1)] = { MM_I2C1 },
+    [PM_RESET_IDX(PM_RESET_TTC0)] = { MM_TTC0 },
+    [PM_RESET_IDX(PM_RESET_TTC1)] = { MM_TTC1 },
+    [PM_RESET_IDX(PM_RESET_TTC2)] = { MM_TTC2 },
+    [PM_RESET_IDX(PM_RESET_TTC3)] = { MM_TTC3 },
+    [PM_RESET_IDX(PM_RESET_SWDT_CRL)] = { MM_SWDT },
+    [PM_RESET_IDX(PM_RESET_NAND)] = { MM_NAND },
+    /* ADMA Channel 0 grants access to pull the reset signal.  */
+    [PM_RESET_IDX(PM_RESET_ADMA)] = { MM_ADMA_CH0 },
+    [PM_RESET_IDX(PM_RESET_GPIO)] = { MM_GPIO },
+    /* FIXME: What is this?  */
+    [PM_RESET_IDX(PM_RESET_IOU_CC)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_TIMESTAMP)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RPU_R50)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_RPU_R51)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_RPU_AMBA)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_OCM)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RPU_PGE)] = { MM_RPU },
+
+    [PM_RESET_IDX(PM_RESET_USB0_CORERESET)] = { MM_USB3_0 },
+    [PM_RESET_IDX(PM_RESET_USB0_HIBERRESET)] = { MM_USB3_0 },
+    [PM_RESET_IDX(PM_RESET_USB0_APB)] = { MM_USB3_0 },
+
+    [PM_RESET_IDX(PM_RESET_USB1_CORERESET)] = { MM_USB3_1 },
+    [PM_RESET_IDX(PM_RESET_USB1_HIBERRESET)] = { MM_USB3_1 },
+    [PM_RESET_IDX(PM_RESET_USB1_APB)] = { MM_USB3_1 },
+
+    [PM_RESET_IDX(PM_RESET_IPI)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_APM_LPD)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RTC)] = { MM_RTC },
+    [PM_RESET_IDX(PM_RESET_SYSMON)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_AFI_FM6)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_LPD_SWDT)] = { MM_SWDT },
+    [PM_RESET_IDX(PM_RESET_FPD)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RPU_DBG1)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_RPU_DBG0)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_DBG_LPD)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_DBG_FPD)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_APLL)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_DPLL)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_VPLL)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_IOPLL)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RPLL)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_0)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_1)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_2)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_3)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_4)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_5)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_6)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_7)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_8)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_9)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_10)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_11)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_12)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_13)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_14)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_15)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_16)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_17)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_18)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_19)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_20)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_21)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_22)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_23)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_24)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_25)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_26)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_27)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_28)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_29)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_30)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_GPO3_PL_31)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_RPU_LS)] = { MM_RPU },
+    [PM_RESET_IDX(PM_RESET_PS_ONLY)] = { .hwdom_access = true },
+    [PM_RESET_IDX(PM_RESET_PL)] = { .hwdom_access = true },
+};
+
+/*
+ * This table maps reset line IDs into a memory address.
+ * If a guest has access to the address, it has enough control
+ * over the affected node to grant it access to EEMI calls for
+ * resetting that node.
+ */
+static const struct {
+    uint64_t start;
+    uint64_t end;    /* Inclusive. If not set, single reg entry.  */
+    uint32_t mask;   /* Zero means no mask, i.e all bits.  */
+    enum pm_node_id node;
+    bool hwdom_access;
+    bool readonly;
+} pm_mmio_access[] = {
+    {
+        .start = MM_CRF_APB + R_CRF_APLL_CTRL,
+        .end = MM_CRF_APB + R_CRF_ACPU_CTRL,
+        .hwdom_access = true
+    },
+    {
+        .start = MM_CRL_APB + R_CRL_IOPLL_CTRL,
+        .end = MM_CRL_APB + R_CRL_RPLL_TO_FPD_CTRL,
+        .hwdom_access = true
+    },
+    { .start = MM_CRF_APB + R_CRF_DP_VIDEO_REF_CTRL, .node = NODE_DP },
+    { .start = MM_CRF_APB + R_CRF_DP_STC_REF_CTRL, .node = NODE_DP },
+    { .start = MM_CRF_APB + R_CRF_GPU_REF_CTRL, .node = NODE_GPU },
+    { .start = MM_CRF_APB + R_CRF_SATA_REF_CTRL, .node = NODE_SATA },
+    { .start = MM_CRF_APB + R_CRF_PCIE_REF_CTRL, .node = NODE_PCIE },
+    { .start = MM_CRF_APB + R_CRF_GDMA_REF_CTRL, .node = NODE_GDMA },
+    { .start = MM_CRF_APB + R_CRF_DPDMA_REF_CTRL, .node = NODE_DP },
+    { .start = MM_CRL_APB + R_CRL_USB3_DUAL_REF_CTRL, .node = NODE_USB_0 },
+    { .start = MM_CRL_APB + R_CRL_USB0_BUS_REF_CTRL, .node = NODE_USB_0 },
+    { .start = MM_CRL_APB + R_CRL_USB1_BUS_REF_CTRL, .node = NODE_USB_1 },
+    { .start = MM_CRL_APB + R_CRL_USB1_BUS_REF_CTRL, .node = NODE_USB_1 },
+    { .start = MM_CRL_APB + R_CRL_GEM0_REF_CTRL, .node = NODE_ETH_0 },
+    { .start = MM_CRL_APB + R_CRL_GEM1_REF_CTRL, .node = NODE_ETH_1 },
+    { .start = MM_CRL_APB + R_CRL_GEM2_REF_CTRL, .node = NODE_ETH_2 },
+    { .start = MM_CRL_APB + R_CRL_GEM3_REF_CTRL, .node = NODE_ETH_3 },
+    { .start = MM_CRL_APB + R_CRL_QSPI_REF_CTRL, .node = NODE_QSPI },
+    { .start = MM_CRL_APB + R_CRL_SDIO0_REF_CTRL, .node = NODE_SD_0 },
+    { .start = MM_CRL_APB + R_CRL_SDIO1_REF_CTRL, .node = NODE_SD_1 },
+    { .start = MM_CRL_APB + R_CRL_UART0_REF_CTRL, .node = NODE_UART_0 },
+    { .start = MM_CRL_APB + R_CRL_UART1_REF_CTRL, .node = NODE_UART_1 },
+    { .start = MM_CRL_APB + R_CRL_SPI0_REF_CTRL, .node = NODE_SPI_0 },
+    { .start = MM_CRL_APB + R_CRL_SPI1_REF_CTRL, .node = NODE_SPI_1 },
+    { .start = MM_CRL_APB + R_CRL_CAN0_REF_CTRL, .node = NODE_CAN_0 },
+    { .start = MM_CRL_APB + R_CRL_CAN1_REF_CTRL, .node = NODE_CAN_1 },
+    { .start = MM_CRL_APB + R_CRL_CPU_R5_CTRL, .node = NODE_RPU },
+    { .start = MM_CRL_APB + R_CRL_IOU_SWITCH_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_CSU_PLL_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PCAP_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_LPD_SWITCH_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_LPD_LSBUS_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_DBG_LPD_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_NAND_REF_CTRL, .node = NODE_NAND },
+    { .start = MM_CRL_APB + R_CRL_ADMA_REF_CTRL, .node = NODE_ADMA },
+    { .start = MM_CRL_APB + R_CRL_PL0_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL1_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL2_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL3_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL0_THR_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL1_THR_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL2_THR_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL3_THR_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL0_THR_CNT, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL1_THR_CNT, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL2_THR_CNT, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_PL3_THR_CNT, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_GEM_TSU_REF_CTRL, .node = NODE_ETH_0 },
+    { .start = MM_CRL_APB + R_CRL_DLL_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_AMS_REF_CTRL, .hwdom_access = true },
+    { .start = MM_CRL_APB + R_CRL_I2C0_REF_CTRL, .node = NODE_I2C_0 },
+    { .start = MM_CRL_APB + R_CRL_I2C1_REF_CTRL, .node = NODE_I2C_1 },
+    { .start = MM_CRL_APB + R_CRL_TIMESTAMP_REF_CTRL, .hwdom_access = true },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_WDT_CLK_SEL, .hwdom_access = true },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_CAN_MIO_CTRL,
+        .mask = 0x1ff, .node = NODE_CAN_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_CAN_MIO_CTRL,
+        .mask = 0x1ff << 15, .node = NODE_CAN_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CLK_CTRL,
+        .mask = 0xf, .node = NODE_ETH_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CLK_CTRL,
+        .mask = 0xf << 5, .node = NODE_ETH_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CLK_CTRL,
+        .mask = 0xf << 10, .node = NODE_ETH_2
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CLK_CTRL,
+        .mask = 0xf << 15, .node = NODE_ETH_3
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CLK_CTRL,
+        .mask = 0x7 << 20, .hwdom_access = true
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_SDIO_CLK_CTRL,
+        .mask = 0x7, .node = NODE_SD_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_SDIO_CLK_CTRL,
+        .mask = 0x7 << 17, .node = NODE_SD_1
+    },
+
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_CTRL_REG_SD,
+        .mask = 0x1, .node = NODE_SD_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_CTRL_REG_SD,
+        .mask = 0x1 << 15, .node = NODE_SD_1
+    },
+    /* A series of SD regs with the same layout.  */
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_SD_ITAPDLY,
+        .end = MM_IOU_SLCR + R_IOU_SLCR_SD_CDN_CTRL,
+        .mask = 0x3ff << 0, .node = NODE_SD_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_SD_ITAPDLY,
+        .end = MM_IOU_SLCR + R_IOU_SLCR_SD_CDN_CTRL,
+        .mask = 0x3ff << 16, .node = NODE_SD_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CTRL,
+        .mask = 0x3 << 0, .node = NODE_ETH_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CTRL,
+        .mask = 0x3 << 2, .node = NODE_ETH_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CTRL,
+        .mask = 0x3 << 4, .node = NODE_ETH_2
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_GEM_CTRL,
+        .mask = 0x3 << 6, .node = NODE_ETH_3
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TTC_APB_CLK,
+        .mask = 0x3 << 0, .node = NODE_TTC_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TTC_APB_CLK,
+        .mask = 0x3 << 2, .node = NODE_TTC_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TTC_APB_CLK,
+        .mask = 0x3 << 4, .node = NODE_TTC_2
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TTC_APB_CLK,
+        .mask = 0x3 << 6, .node = NODE_TTC_3
+    },
+
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TAPDLY_BYPASS,
+        .mask = 0x3, .node = NODE_NAND
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_TAPDLY_BYPASS,
+        .mask = 0x1 << 2, .node = NODE_QSPI
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 0, .node = NODE_ETH_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 4, .node = NODE_ETH_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 8, .node = NODE_ETH_2
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 12, .node = NODE_ETH_3
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 16, .node = NODE_SD_0
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 20, .node = NODE_SD_1
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 24, .node = NODE_NAND
+    },
+    {
+        .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_COHERENT_CTRL,
+        .mask = 0xf << 28, .node = NODE_QSPI
+    },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_VIDEO_PSS_CLK_SEL, .hwdom_access = true },
+    /* No access to R_IOU_SLCR_IOU_INTERCONNECT_ROUTE at all.  */
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_GEM0, .node = NODE_ETH_0 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_GEM1, .node = NODE_ETH_1 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_GEM2, .node = NODE_ETH_2 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_GEM3, .node = NODE_ETH_3 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_SD0, .node = NODE_SD_0 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_SD1, .node = NODE_SD_1 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_CAN0, .node = NODE_CAN_0 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_CAN1, .node = NODE_CAN_1 },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_LQSPI, .node = NODE_QSPI },
+    { .start = MM_IOU_SLCR + R_IOU_SLCR_IOU_RAM_NAND, .node = NODE_NAND },
+    {
+        .start = MM_PMU_GLOBAL + R_PMU_GLOBAL_PWR_STATE,
+        .readonly = true,
+    },
+    {
+        .start = MM_PMU_GLOBAL + R_PMU_GLOBAL_GLOBAL_GEN_STORAGE0,
+        .end = MM_PMU_GLOBAL + R_PMU_GLOBAL_PERS_GLOB_GEN_STORAGE7,
+        .readonly = true,
+    },
+    {
+        /* Universal read-only access to CRF. Linux CCF needs this.  */
+        .start = MM_CRF_APB, .end = MM_CRF_APB + 0x104,
+        .readonly = true,
+    },
+    {
+        /* Universal read-only access to CRL. Linux CCF needs this.  */
+        .start = MM_CRL_APB, .end = MM_CRL_APB + 0x284,
+        .readonly = true,
+    }
+};
+
+static bool pm_check_access(const struct pm_access *acl, struct domain *d, int idx)
+{
+    unsigned long mfn;
+
+    if ( acl[idx].hwdom_access && is_hardware_domain(d) )
+        return true;
+
+    mfn = paddr_to_pfn(acl[idx].addr);
+    if ( !mfn )
+        return false;
+
+    return iomem_access_permitted(d, mfn, mfn);
+}
+
+/* Check if a domain has access to a node.  */
+static bool domain_has_node_access(struct domain *d, enum pm_node_id node)
+{
+    if ( node <= 0 || node > ARRAY_SIZE(pm_node_access) )
+        return false;
+
+    /* NODE_UNKNOWN is treated as a wildcard.  */
+    if ( node == NODE_UNKNOWN )
+        return true;
+
+    return pm_check_access(pm_node_access, d, node);
+}
+
+/* Check if a domain has access to a reset line.  */
+static bool domain_has_reset_access(struct domain *d, enum pm_reset rst)
+{
+    int rst_idx = PM_RESET_IDX(rst);
+
+    if ( rst_idx < 0 || rst_idx > ARRAY_SIZE(pm_reset_access) )
+        return false;
+
+    return pm_check_access(pm_reset_access, d, rst_idx);
+}
+
+/*
+ * Check if a given domain has access to perform an indirect
+ * MMIO access.
+ *
+ * If the provided mask is invalid, it will be fixed up.
+ */
+static bool domain_mediate_mmio_access(struct domain *d,
+                                       bool write, uint64_t addr,
+                                       uint32_t *mask)
+{
+    unsigned int i;
+    bool ret = false;
+    uint32_t prot_mask = 0;
+
+    ASSERT(mask);
+
+    /*
+     * The hardware domain gets read access to everything.
+     * Lower layers will do further filtering.
+     */
+    if ( !write && is_hardware_domain(d) )
+        return true;
+
+    /* Scan the ACL.  */
+    for ( i = 0; i < ARRAY_SIZE(pm_mmio_access); i++ ) {
+        bool r;
+
+        /* Check if the address is OK.  */
+        if ( pm_mmio_access[i].end ) {
+            /* Memory range.  */
+            if ( addr < pm_mmio_access[i].start )
+                continue;
+            if ( addr > pm_mmio_access[i].end )
+                continue;
+        } else {
+            /* Single register.  */
+            if ( addr != pm_mmio_access[i].start )
+                continue;
+        }
+
+        if ( write && pm_mmio_access[i].readonly )
+            continue;
+        if ( pm_mmio_access[i].hwdom_access && !is_hardware_domain(d) )
+            continue;
+
+        /* Unlimited access is represented by a zero mask.  */
+        ASSERT( pm_mmio_access[i].mask != 0xFFFFFFFF );
+
+        r = domain_has_node_access(d, pm_mmio_access[i].node);
+        if ( r ) {
+            /* We've got access to this reg (or parts of it).  */
+            ret = true;
+            /* Masking only applies to writes, so reads can exit here.  */
+            if ( !write )
+                break;
+
+            /* Permit write access to selected bits.  */
+            prot_mask |= pm_mmio_access[i].mask ? pm_mmio_access[i].mask : ~0;
+            printk("match: mask=%x prot_mask=%x\n",
+                   pm_mmio_access[i].mask, prot_mask);
+            if ( prot_mask == 0xFFFFFFFF )
+                break; /* Full access, we're done.  */
+        } else {
+            if ( !pm_mmio_access[i].mask ) {
+                /*
+                 * The entire reg is tied to a device that we don't have
+                 * access to. No point in continuing.
+                 */
+                return false;
+            }
+        }
+    }
+
+    /* Masking only applies to writes.  */
+    if ( write )
+        *mask &= prot_mask;
+    return ret;
+}
+
+bool zynqmp_eemi_mediate(register_t fid,
+                         register_t a0,
+                         register_t a1,
+                         register_t a2,
+                         register_t a3,
+                         register_t a4,
+                         register_t a5,
+                         register_t *ret)
+{
+    bool is_mmio_write = false;
+    unsigned int pm_fn = fid & 0xFFFF;
+    uint32_t pm_arg[4];
+
+    /* Decode pm args.  */
+    pm_arg[0] = a0;
+    pm_arg[1] = a0 >> 32;
+    pm_arg[2] = a1;
+    pm_arg[3] = a1 >> 32;
+
+    ASSERT(ret);
+
+    switch (pm_fn)
+    {
+    /*
+     * We can't allow CPUs to suspend without Xen knowing about it.
+     * We accept but ignore the request and wait for the guest to issue
+     * a WFI which Xen will trap and act accordingly upon.
+     */
+    case PM_SELF_SUSPEND:
+        ret[0] = PM_RET_SUCCESS;
+        goto done;
+
+    case PM_GET_NODE_STATUS:
+    /* API for PUs.  */
+    case PM_REQ_SUSPEND:
+    case PM_FORCE_POWERDOWN:
+    case PM_ABORT_SUSPEND:
+    case PM_REQ_WAKEUP:
+    case PM_SET_WAKEUP_SOURCE:
+    /* API for slaves.  */
+    case PM_REQ_NODE:
+    case PM_RELEASE_NODE:
+    case PM_SET_REQUIREMENT:
+    case PM_SET_MAX_LATENCY:
+        if ( !domain_has_node_access(current->domain, pm_arg[0]) ) {
+            printk("zynqmp-pm: fn=%d No access to node %d\n", pm_fn, pm_arg[0]);
+            ret[0] = PM_RET_ERROR_ACCESS;
+            goto done;
+        }
+        goto forward_to_fw;
+
+    case PM_RESET_ASSERT:
+    case PM_RESET_GET_STATUS:
+        if ( !domain_has_reset_access(current->domain, pm_arg[0]) ) {
+            printk("zynqmp-pm: fn=%d No access to reset %d\n", pm_fn, pm_arg[0]);
+            ret[0] = PM_RET_ERROR_ACCESS;
+            goto done;
+        }
+        goto forward_to_fw;
+
+    /* These calls are safe and always allowed.  */
+    case ZYNQMP_SIP_SVC_CALL_COUNT:
+    case ZYNQMP_SIP_SVC_UID:
+    case ZYNQMP_SIP_SVC_VERSION:
+    case PM_GET_API_VERSION:
+    case PM_GET_CHIPID:
+        goto forward_to_fw;
+
+    /* Mediated MMIO access.  */
+    case PM_MMIO_WRITE:
+        is_mmio_write = true;
+    /* Fallthrough.  */
+    case PM_MMIO_READ:
+        if ( !domain_mediate_mmio_access(current->domain,
+                                         is_mmio_write,
+                                         pm_arg[0], &pm_arg[1]) ) {
+            printk("eemi: fn=%d No access to MMIO %s %x\n",
+                   pm_fn, is_mmio_write ? "write" : "read", pm_arg[0]);
+            ret[0] = PM_RET_ERROR_ACCESS;
+            goto done;
+        }
+        goto forward_to_fw;
+
+    /* Exclusive to Dom0.  */
+    case PM_INIT:
+    case PM_SET_CONFIGURATION:
+    case PM_FPGA_LOAD:
+    case PM_FPGA_GET_STATUS:
+        if ( !is_hardware_domain(current->domain) ) {
+            printk("eemi: fn=%d No access", pm_fn);
+            ret[0] = PM_RET_ERROR_ACCESS;
+            goto done;
+        }
+        goto forward_to_fw;
+
+    /* These calls are never allowed.  */
+    case PM_SYSTEM_SHUTDOWN:
+        ret[0] = PM_RET_ERROR_ACCESS;
+        goto done;
+
+    default:
+        printk("zynqmp-pm: Unhandled PM Call: %d\n", (u32)fid);
+        return false;
+    }
+
+forward_to_fw:
+    /* Re-encode pm args.  */
+    a0 = ((uint64_t)pm_arg[1] << 32) | pm_arg[0];
+    a1 = ((uint64_t)pm_arg[3] << 32) | pm_arg[2];
+    call_smcc64(fid, a0, a1, a2, a3, a4, a5, ret);
+done:
+    return true;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/platforms/xilinx-zynqmp.c b/xen/arch/arm/platforms/xilinx-zynqmp.c
index 2adee91..d826282 100644
--- a/xen/arch/arm/platforms/xilinx-zynqmp.c
+++ b/xen/arch/arm/platforms/xilinx-zynqmp.c
@@ -18,6 +18,7 @@
  */
 
 #include <asm/platform.h>
+#include <asm/platforms/xilinx-zynqmp-eemi.h>
 
 static const char * const zynqmp_dt_compat[] __initconst =
 {
@@ -32,8 +33,25 @@ static const struct dt_device_match zynqmp_blacklist_dev[] __initconst =
     { /* sentinel */ },
 };
 
+bool zynqmp_hvc(struct cpu_user_regs *regs)
+{
+    register_t ret[4] = { 0 };
+
+    if ( !zynqmp_eemi_mediate(regs->x0, regs->x1, regs->x2, regs->x3,
+                              regs->x4, regs->x5, regs->x6, ret) )
+        return false;
+
+    /* Transfer return values into guest registers.  */
+    regs->x0 = ret[0];
+    regs->x1 = ret[1];
+    regs->x2 = ret[2];
+    regs->x3 = ret[3];
+    return true;
+}
+
 PLATFORM_START(xgene_storm, "Xilinx ZynqMP")
     .compatible = zynqmp_dt_compat,
+    .hvc = zynqmp_hvc,
     .blacklist_dev = zynqmp_blacklist_dev,
 PLATFORM_END
 
diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h
new file mode 100644
index 0000000..774593c
--- /dev/null
+++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h
@@ -0,0 +1,337 @@
+/* Xen specifics:  */
+/* Main PM Mediator entry.  */
+bool zynqmp_eemi_mediate(register_t fid,
+                         register_t a0,
+                         register_t a1,
+                         register_t a2,
+                         register_t a3,
+                         register_t a4,
+                         register_t a5,
+                         register_t *ret);
+
+/* Service calls.  */
+#define SVC_MASK             0x3F000000
+#define SVC_SIP              0x02000000    /* SoC Implementation Specific.  */
+#define PM_SIP_SVC           0xC2000000
+
+/* SMC function IDs for SiP Service queries */
+#define ZYNQMP_SIP_SVC_CALL_COUNT       0xff00
+#define ZYNQMP_SIP_SVC_UID              0xff01
+#define ZYNQMP_SIP_SVC_VERSION          0xff03
+
+/* Generic PM defs:  */
+/*
+ * Version number is a 32bit value, like:
+ * (PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR
+ */
+#define PM_VERSION_MAJOR	0
+#define PM_VERSION_MINOR	2
+
+#define PM_VERSION	((PM_VERSION_MAJOR << 16) | PM_VERSION_MINOR)
+
+/* Capabilities for RAM */
+#define PM_CAP_ACCESS	0x1U
+#define PM_CAP_CONTEXT	0x2U
+
+#define MAX_LATENCY	(~0U)
+#define MAX_QOS		100U
+
+/* State arguments of the self suspend */
+#define PM_STATE_CPU_IDLE		0x0U
+#define PM_STATE_SUSPEND_TO_RAM		0xFU
+
+enum pm_api_id {
+	/* Miscellaneous API functions: */
+	PM_GET_API_VERSION = 1, /* Do not change or move */
+	PM_SET_CONFIGURATION,
+	PM_GET_NODE_STATUS,
+	PM_GET_OP_CHARACTERISTIC,
+	PM_REGISTER_NOTIFIER,
+	/* API for suspending of PUs: */
+	PM_REQ_SUSPEND,
+	PM_SELF_SUSPEND,
+	PM_FORCE_POWERDOWN,
+	PM_ABORT_SUSPEND,
+	PM_REQ_WAKEUP,
+	PM_SET_WAKEUP_SOURCE,
+	PM_SYSTEM_SHUTDOWN,
+	/* API for managing PM slaves: */
+	PM_REQ_NODE,
+	PM_RELEASE_NODE,
+	PM_SET_REQUIREMENT,
+	PM_SET_MAX_LATENCY,
+	/* Direct control API functions: */
+	PM_RESET_ASSERT,
+	PM_RESET_GET_STATUS,
+	PM_MMIO_WRITE,
+	PM_MMIO_READ,
+	PM_INIT,
+	PM_FPGA_LOAD,
+	PM_FPGA_GET_STATUS,
+	PM_GET_CHIPID,
+	PM_API_MAX
+};
+
+enum pm_node_id {
+	NODE_UNKNOWN = 0,
+	NODE_APU,
+	NODE_APU_0,
+	NODE_APU_1,
+	NODE_APU_2,
+	NODE_APU_3,
+	NODE_RPU,
+	NODE_RPU_0,
+	NODE_RPU_1,
+	NODE_PL,
+	NODE_FPD,
+	NODE_OCM_BANK_0,
+	NODE_OCM_BANK_1,
+	NODE_OCM_BANK_2,
+	NODE_OCM_BANK_3,
+	NODE_TCM_0_A,
+	NODE_TCM_0_B,
+	NODE_TCM_1_A,
+	NODE_TCM_1_B,
+	NODE_L2,
+	NODE_GPU_PP_0,
+	NODE_GPU_PP_1,
+	NODE_USB_0,
+	NODE_USB_1,
+	NODE_TTC_0,
+	NODE_TTC_1,
+	NODE_TTC_2,
+	NODE_TTC_3,
+	NODE_SATA,
+	NODE_ETH_0,
+	NODE_ETH_1,
+	NODE_ETH_2,
+	NODE_ETH_3,
+	NODE_UART_0,
+	NODE_UART_1,
+	NODE_SPI_0,
+	NODE_SPI_1,
+	NODE_I2C_0,
+	NODE_I2C_1,
+	NODE_SD_0,
+	NODE_SD_1,
+	NODE_DP,
+	NODE_GDMA,
+	NODE_ADMA,
+	NODE_NAND,
+	NODE_QSPI,
+	NODE_GPIO,
+	NODE_CAN_0,
+	NODE_CAN_1,
+	NODE_AFI,
+	NODE_APLL,
+	NODE_VPLL,
+	NODE_DPLL,
+	NODE_RPLL,
+	NODE_IOPLL,
+	NODE_DDR,
+	NODE_IPI_APU,
+	NODE_IPI_RPU_0,
+	NODE_GPU,
+	NODE_PCIE,
+	NODE_PCAP,
+	NODE_RTC,
+	NODE_MAX
+};
+
+enum pm_request_ack {
+	REQ_ACK_NO = 1,
+	REQ_ACK_BLOCKING,
+	REQ_ACK_NON_BLOCKING,
+};
+
+enum pm_abort_reason {
+	ABORT_REASON_WKUP_EVENT = 100,
+	ABORT_REASON_PU_BUSY,
+	ABORT_REASON_NO_PWRDN,
+	ABORT_REASON_UNKNOWN,
+};
+
+enum pm_suspend_reason {
+	SUSPEND_REASON_PU_REQ = 201,
+	SUSPEND_REASON_ALERT,
+	SUSPEND_REASON_SYS_SHUTDOWN,
+};
+
+enum pm_ram_state {
+	PM_RAM_STATE_OFF = 1,
+	PM_RAM_STATE_RETENTION,
+	PM_RAM_STATE_ON,
+};
+
+enum pm_opchar_type {
+	PM_OPCHAR_TYPE_POWER = 1,
+	PM_OPCHAR_TYPE_TEMP,
+	PM_OPCHAR_TYPE_LATENCY,
+};
+
+/**
+ * @PM_RET_SUCCESS:		success
+ * @PM_RET_ERROR_ARGS:		illegal arguments provided
+ * @PM_RET_ERROR_ACCESS:	access rights violation
+ * @PM_RET_ERROR_TIMEOUT:	timeout in communication with PMU
+ * @PM_RET_ERROR_NOTSUPPORTED:	feature not supported
+ * @PM_RET_ERROR_PROC:		node is not a processor node
+ * @PM_RET_ERROR_API_ID:	illegal API ID
+ * @PM_RET_ERROR_OTHER:		other error
+ */
+enum pm_ret_status {
+	PM_RET_SUCCESS,
+	PM_RET_ERROR_ARGS,
+	PM_RET_ERROR_ACCESS,
+	PM_RET_ERROR_TIMEOUT,
+	PM_RET_ERROR_NOTSUPPORTED,
+	PM_RET_ERROR_PROC,
+	PM_RET_ERROR_API_ID,
+	PM_RET_ERROR_FAILURE,
+	PM_RET_ERROR_COMMUNIC,
+	PM_RET_ERROR_DOUBLEREQ,
+	PM_RET_ERROR_OTHER,
+};
+
+/**
+ * @PM_INITIAL_BOOT:	boot is a fresh system startup
+ * @PM_RESUME:		boot is a resume
+ * @PM_BOOT_ERROR:	error, boot cause cannot be identified
+ */
+enum pm_boot_status {
+	PM_INITIAL_BOOT,
+	PM_RESUME,
+	PM_BOOT_ERROR,
+};
+
+enum pm_shutdown_type {
+	PMF_SHUTDOWN_TYPE_SHUTDOWN,
+	PMF_SHUTDOWN_TYPE_RESET,
+};
+
+enum pm_shutdown_subtype {
+	PMF_SHUTDOWN_SUBTYPE_SUBSYSTEM,
+	PMF_SHUTDOWN_SUBTYPE_PS_ONLY,
+	PMF_SHUTDOWN_SUBTYPE_SYSTEM,
+};
+
+enum pm_reset {
+	PM_RESET_START = 999,
+	PM_RESET_PCIE_CFG,
+	PM_RESET_PCIE_BRIDGE,
+	PM_RESET_PCIE_CTRL,
+	PM_RESET_DP,
+	PM_RESET_SWDT_CRF,
+	PM_RESET_AFI_FM5,
+	PM_RESET_AFI_FM4,
+	PM_RESET_AFI_FM3,
+	PM_RESET_AFI_FM2,
+	PM_RESET_AFI_FM1,
+	PM_RESET_AFI_FM0,
+	PM_RESET_GDMA,
+	PM_RESET_GPU_PP1,
+	PM_RESET_GPU_PP0,
+	PM_RESET_GPU,
+	PM_RESET_GT,
+	PM_RESET_SATA,
+	PM_RESET_ACPU3_PWRON,
+	PM_RESET_ACPU2_PWRON,
+	PM_RESET_ACPU1_PWRON,
+	PM_RESET_ACPU0_PWRON,
+	PM_RESET_APU_L2,
+	PM_RESET_ACPU3,
+	PM_RESET_ACPU2,
+	PM_RESET_ACPU1,
+	PM_RESET_ACPU0,
+	PM_RESET_DDR,
+	PM_RESET_APM_FPD,
+	PM_RESET_SOFT,
+	PM_RESET_GEM0,
+	PM_RESET_GEM1,
+	PM_RESET_GEM2,
+	PM_RESET_GEM3,
+	PM_RESET_QSPI,
+	PM_RESET_UART0,
+	PM_RESET_UART1,
+	PM_RESET_SPI0,
+	PM_RESET_SPI1,
+	PM_RESET_SDIO0,
+	PM_RESET_SDIO1,
+	PM_RESET_CAN0,
+	PM_RESET_CAN1,
+	PM_RESET_I2C0,
+	PM_RESET_I2C1,
+	PM_RESET_TTC0,
+	PM_RESET_TTC1,
+	PM_RESET_TTC2,
+	PM_RESET_TTC3,
+	PM_RESET_SWDT_CRL,
+	PM_RESET_NAND,
+	PM_RESET_ADMA,
+	PM_RESET_GPIO,
+	PM_RESET_IOU_CC,
+	PM_RESET_TIMESTAMP,
+	PM_RESET_RPU_R50,
+	PM_RESET_RPU_R51,
+	PM_RESET_RPU_AMBA,
+	PM_RESET_OCM,
+	PM_RESET_RPU_PGE,
+	PM_RESET_USB0_CORERESET,
+	PM_RESET_USB1_CORERESET,
+	PM_RESET_USB0_HIBERRESET,
+	PM_RESET_USB1_HIBERRESET,
+	PM_RESET_USB0_APB,
+	PM_RESET_USB1_APB,
+	PM_RESET_IPI,
+	PM_RESET_APM_LPD,
+	PM_RESET_RTC,
+	PM_RESET_SYSMON,
+	PM_RESET_AFI_FM6,
+	PM_RESET_LPD_SWDT,
+	PM_RESET_FPD,
+	PM_RESET_RPU_DBG1,
+	PM_RESET_RPU_DBG0,
+	PM_RESET_DBG_LPD,
+	PM_RESET_DBG_FPD,
+	PM_RESET_APLL,
+	PM_RESET_DPLL,
+	PM_RESET_VPLL,
+	PM_RESET_IOPLL,
+	PM_RESET_RPLL,
+	PM_RESET_GPO3_PL_0,
+	PM_RESET_GPO3_PL_1,
+	PM_RESET_GPO3_PL_2,
+	PM_RESET_GPO3_PL_3,
+	PM_RESET_GPO3_PL_4,
+	PM_RESET_GPO3_PL_5,
+	PM_RESET_GPO3_PL_6,
+	PM_RESET_GPO3_PL_7,
+	PM_RESET_GPO3_PL_8,
+	PM_RESET_GPO3_PL_9,
+	PM_RESET_GPO3_PL_10,
+	PM_RESET_GPO3_PL_11,
+	PM_RESET_GPO3_PL_12,
+	PM_RESET_GPO3_PL_13,
+	PM_RESET_GPO3_PL_14,
+	PM_RESET_GPO3_PL_15,
+	PM_RESET_GPO3_PL_16,
+	PM_RESET_GPO3_PL_17,
+	PM_RESET_GPO3_PL_18,
+	PM_RESET_GPO3_PL_19,
+	PM_RESET_GPO3_PL_20,
+	PM_RESET_GPO3_PL_21,
+	PM_RESET_GPO3_PL_22,
+	PM_RESET_GPO3_PL_23,
+	PM_RESET_GPO3_PL_24,
+	PM_RESET_GPO3_PL_25,
+	PM_RESET_GPO3_PL_26,
+	PM_RESET_GPO3_PL_27,
+	PM_RESET_GPO3_PL_28,
+	PM_RESET_GPO3_PL_29,
+	PM_RESET_GPO3_PL_30,
+	PM_RESET_GPO3_PL_31,
+	PM_RESET_RPU_LS,
+	PM_RESET_PS_ONLY,
+	PM_RESET_PL,
+	PM_RESET_END
+};
diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-mm.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-mm.h
new file mode 100644
index 0000000..4fb1695
--- /dev/null
+++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-mm.h
@@ -0,0 +1,284 @@
+/*
+ * Merge of various auto-generated memory map and register
+ * definition files.
+ */
+
+/* Selected set of memory-map definitions:  */
+#define MM_IOU_S	0xff000000
+#define MM_IPI	0xff300000
+#define MM_LPD_SLCR	0xff410000
+#define MM_LPD_SLCR_SECURE	0xff4b0000
+#define MM_CRL_APB	0xff5e0000
+#define MM_OCM	0xff960000
+#define MM_LPD_XPPU	0xff980000
+#define MM_RPU	0xff9a0000
+#define MM_AFIFM6	0xff9b0000
+#define MM_LPD_XPPU_SINK	0xff9c0000
+#define MM_USB3_0	0xff9d0000
+#define MM_USB3_1	0xff9e0000
+#define MM_APM_INTC_OCM	0xffa00000
+#define MM_APM_LPD_FPD	0xffa10000
+#define MM_AMS_CTRL	0xffa50000
+#define MM_AMS_PS_SYSMON	0xffa50800
+#define MM_AMS_PL_SYSMON	0xffa50c00
+#define MM_RTC	0xffa60000
+#define MM_OCM_XMPU_CFG	0xffa70000
+#define MM_ADMA_CH0	0xffa80000
+#define MM_ADMA_CH1	0xffa90000
+#define MM_ADMA_CH2	0xffaa0000
+#define MM_ADMA_CH3	0xffab0000
+#define MM_ADMA_CH4	0xffac0000
+#define MM_ADMA_CH5	0xffad0000
+#define MM_ADMA_CH6	0xffae0000
+
+#define MM_IOU_GPV	0xfe0fffff
+#define MM_LPD_GPV	0xfe1fffff
+#define MM_USB3_0_XHCI	0xfe2fffff
+#define MM_USB3_1_XHCI	0xfe3fffff
+#define MM_CORESIGHT_SOC_ROM	0xfe80ffff
+#define MM_CORESIGHT_SOC_TSGEN	0xfe90ffff
+#define MM_CORESIGHT_SOC_FUNN_0	0xfe91ffff
+#define MM_CORESIGHT_SOC_FUNN_1	0xfe92ffff
+#define MM_CORESIGHT_SOC_FUNN_2	0xfe93ffff
+#define MM_CORESIGHT_SOC_ETF_1	0xfe94ffff
+#define MM_CORESIGHT_SOC_ETF_2	0xfe95ffff
+#define MM_CORESIGHT_SOC_REPLIC	0xfe96ffff
+#define MM_CORESIGHT_SOC_ETR	0xfe97ffff
+#define MM_CORESIGHT_SOC_TPIU	0xfe98ffff
+#define MM_CORESIGHT_SOC_CTI_0	0xfe99ffff
+#define MM_CORESIGHT_SOC_CTI_1	0xfe9affff
+#define MM_CORESIGHT_SOC_CTI_2	0xfe9bffff
+#define MM_CORESIGHT_SOC_STM	0xfe9cffff
+#define MM_CORESIGHT_SOC_FTM	0xfe9dffff
+#define MM_CORESIGHT_SOC_ATM_0	0xfe9effff
+#define MM_CORESIGHT_SOC_ATM_1	0xfe9fffff
+#define MM_CORESIGHT_R5_ROM	0xfebe0fff
+#define MM_CORESIGHT_R5_DBG_0	0xfebf0fff
+#define MM_CORESIGHT_R5_PMU_0	0xfebf1fff
+#define MM_CORESIGHT_R5_DBG_1	0xfebf2fff
+#define MM_CORESIGHT_R5_PMU_1	0xfebf3fff
+#define MM_CORESIGHT_R5_CTI_0	0xfebf8fff
+#define MM_CORESIGHT_R5_CTI_1	0xfebf9fff
+#define MM_CORESIGHT_R5_ETM_0	0xfebfcfff
+#define MM_CORESIGHT_R5_ETM_1	0xfebfdfff
+#define MM_CORESIGHT_A53_ROM	0xfec0ffff
+#define MM_CORESIGHT_A53_DBG_0	0xfec1ffff
+#define MM_CORESIGHT_A53_CTI_0	0xfec2ffff
+#define MM_CORESIGHT_A53_PMU_0	0xfec3ffff
+#define MM_CORESIGHT_A53_ETM_0	0xfec4ffff
+#define MM_CORESIGHT_A53_DBG_1	0xfed1ffff
+#define MM_CORESIGHT_A53_CTI_1	0xfed2ffff
+#define MM_CORESIGHT_A53_PMU_1	0xfed3ffff
+#define MM_CORESIGHT_A53_ETM_1	0xfed4ffff
+#define MM_CORESIGHT_A53_DBG_2	0xfee1ffff
+#define MM_CORESIGHT_A53_CTI_2	0xfee2ffff
+#define MM_CORESIGHT_A53_PMU_2	0xfee3ffff
+#define MM_CORESIGHT_A53_ETM_2	0xfee4ffff
+#define MM_CORESIGHT_A53_DBG_3	0xfef1ffff
+#define MM_CORESIGHT_A53_CTI_3	0xfef2ffff
+#define MM_CORESIGHT_A53_PMU_3	0xfef3ffff
+
+#define MM_DDRSS	0xfd000000
+#define MM_SATA_AHCI_HBA	0xfd0c0000
+#define MM_SATA_AHCI_VENDOR	0xfd0c00a0
+#define MM_SATA_AHCI_PORT0_CNTRL	0xfd0c0100
+#define MM_SATA_AHCI_PORT1_CNTRL	0xfd0c0180
+#define MM_AXIPCIE_MAIN	0xfd0e0000
+#define MM_AXIPCIE_INGRESS0	0xfd0e0800
+#define MM_AXIPCIE_INGRESS1	0xfd0e0820
+#define MM_AXIPCIE_INGRESS2	0xfd0e0840
+#define MM_AXIPCIE_INGRESS3	0xfd0e0860
+#define MM_AXIPCIE_INGRESS4	0xfd0e0880
+#define MM_AXIPCIE_INGRESS5	0xfd0e08a0
+#define MM_AXIPCIE_INGRESS6	0xfd0e08c0
+#define MM_AXIPCIE_INGRESS7	0xfd0e08e0
+#define MM_AXIPCIE_EGRESS0	0xfd0e0c00
+#define MM_AXIPCIE_EGRESS1	0xfd0e0c20
+#define MM_AXIPCIE_EGRESS2	0xfd0e0c40
+#define MM_AXIPCIE_EGRESS3	0xfd0e0c60
+#define MM_AXIPCIE_EGRESS4	0xfd0e0c80
+#define MM_AXIPCIE_EGRESS5	0xfd0e0ca0
+#define MM_AXIPCIE_EGRESS6	0xfd0e0cc0
+#define MM_AXIPCIE_EGRESS7	0xfd0e0ce0
+#define MM_AXIPCIE_DMA0	0xfd0f0000
+#define MM_AXIPCIE_DMA1	0xfd0f0080
+#define MM_AXIPCIE_DMA2	0xfd0f0100
+#define MM_AXIPCIE_DMA3	0xfd0f0180
+#define MM_AXIPCIE_MSIX_TABLE	0xfd0f1000
+#define MM_AXIPCIE_MSIX_PBA	0xfd0f2000
+#define MM_CRF_APB	0xfd1a0000
+#define MM_AFIFM0	0xfd360000
+#define MM_AFIFM1	0xfd370000
+#define MM_AFIFM2	0xfd380000
+#define MM_AFIFM3	0xfd390000
+#define MM_AFIFM4	0xfd3a0000
+#define MM_AFIFM5	0xfd3b0000
+#define MM_SIOU	0xfd3d0000
+#define MM_SERDES	0xfd400000
+#define MM_PCIE_ATTRIB	0xfd480000
+#define MM_APM_CCI_INTC	0xfd490000
+#define MM_DP	0xfd4a0000
+#define MM_GPU	0xfd4b0000
+#define MM_DPDMA	0xfd4c0000
+#define MM_WDT	0xfd4d0000
+#define MM_FPD_XMPU_SINK	0xfd4f0000
+#define MM_GDMA_CH0	0xfd500000
+#define MM_GDMA_CH1	0xfd510000
+#define MM_GDMA_CH2	0xfd520000
+#define MM_GDMA_CH3	0xfd530000
+#define MM_GDMA_CH4	0xfd540000
+#define MM_GDMA_CH5	0xfd550000
+#define MM_GDMA_CH6	0xfd560000
+#define MM_GDMA_CH7	0xfd570000
+#define MM_APU	0xfd5c0000
+#define MM_FPD_XMPU_CFG	0xfd5d0000
+#define MM_CCI_REG	0xfd5e0000
+#define MM_SMMU_REG	0xfd5f0000
+#define MM_FPD_SLCR	0xfd610000
+#define MM_FPD_SLCR_SECURE	0xfd690000
+#define MM_CCI_GPV	0xfd6e0000
+#define MM_FPD_GPV	0xfd700000
+
+#define MM_QSPI_Linear_Address	0xc0000000
+#define MM_UART0	0xff000000
+#define MM_UART1	0xff010000
+#define MM_I2C0	0xff020000
+#define MM_I2C1	0xff030000
+#define MM_SPI0	0xff040000
+#define MM_SPI1	0xff050000
+#define MM_CAN0	0xff060000
+#define MM_CAN1	0xff070000
+#define MM_GPIO	0xff0a0000
+#define MM_GEM0	0xff0b0000
+#define MM_GEM1	0xff0c0000
+#define MM_GEM2	0xff0d0000
+#define MM_GEM3	0xff0e0000
+#define MM_QSPI	0xff0f0000
+#define MM_NAND	0xff100000
+#define MM_TTC0	0xff110000
+#define MM_TTC1	0xff120000
+#define MM_TTC2	0xff130000
+#define MM_TTC3	0xff140000
+#define MM_SWDT	0xff150000
+#define MM_SD0	0xff160000
+#define MM_SD1	0xff170000
+#define MM_IOU_SLCR	0xff180000
+#define MM_IOU_SECURE_SLCR	0xff240000
+#define MM_IOU_SCNTR	0xff250000
+
+#define MM_alg_vcu_enc_top	0xa0000000
+#define MM_alg_vcu_dec_top	0xa0020000
+
+#define MM_PMU_GLOBAL           0xffd80000
+#define MM_CSU                  0xffca0000
+
+/* Selected set of register definitions:  */
+#define R_CRF_APLL_CTRL           0x20
+#define R_CRF_ACPU_CTRL           0x60
+#define R_CRF_DP_VIDEO_REF_CTRL   0x70
+#define R_CRF_DP_STC_REF_CTRL     0x7c
+#define R_CRF_GPU_REF_CTRL        0x84
+#define R_CRF_SATA_REF_CTRL       0xa0
+#define R_CRF_PCIE_REF_CTRL       0xb4
+#define R_CRF_GDMA_REF_CTRL       0xb8
+#define R_CRF_DPDMA_REF_CTRL      0xbc
+
+#define R_CRL_IOPLL_CTRL          0x20
+#define R_CRL_IOPLL_CFG           0x24
+#define R_CRL_IOPLL_FRAC_CFG      0x28
+#define R_CRL_RPLL_CTRL           0x30
+#define R_CRL_RPLL_CFG            0x34
+#define R_CRL_RPLL_FRAC_CFG       0x38
+#define R_CRL_PLL_STATUS          0x40
+#define R_CRL_IOPLL_TO_FPD_CTRL   0x44
+#define R_CRL_RPLL_TO_FPD_CTRL    0x48
+#define R_CRL_USB3_DUAL_REF_CTRL  0x4c
+#define R_CRL_GEM0_REF_CTRL       0x50
+#define R_CRL_GEM1_REF_CTRL       0x54
+#define R_CRL_GEM2_REF_CTRL       0x58
+#define R_CRL_GEM3_REF_CTRL       0x5c
+#define R_CRL_USB0_BUS_REF_CTRL   0x60
+#define R_CRL_USB1_BUS_REF_CTRL   0x64
+#define R_CRL_QSPI_REF_CTRL       0x68
+#define R_CRL_SDIO0_REF_CTRL      0x6c
+#define R_CRL_SDIO1_REF_CTRL      0x70
+#define R_CRL_UART0_REF_CTRL      0x74
+#define R_CRL_UART1_REF_CTRL      0x78
+#define R_CRL_SPI0_REF_CTRL       0x7c
+#define R_CRL_SPI1_REF_CTRL       0x80
+#define R_CRL_CAN0_REF_CTRL       0x84
+#define R_CRL_CAN1_REF_CTRL       0x88
+#define R_CRL_CPU_R5_CTRL         0x90
+#define R_CRL_IOU_SWITCH_CTRL     0x9c
+#define R_CRL_CSU_PLL_CTRL        0xa0
+#define R_CRL_PCAP_CTRL           0xa4
+#define R_CRL_LPD_SWITCH_CTRL     0xa8
+#define R_CRL_LPD_LSBUS_CTRL      0xac
+#define R_CRL_DBG_LPD_CTRL        0xb0
+#define R_CRL_NAND_REF_CTRL       0xb4
+#define R_CRL_ADMA_REF_CTRL       0xb8
+#define R_CRL_PL0_REF_CTRL        0xc0
+#define R_CRL_PL1_REF_CTRL        0xc4
+#define R_CRL_PL2_REF_CTRL        0xc8
+#define R_CRL_PL3_REF_CTRL        0xcc
+#define R_CRL_PL0_THR_CTRL        0xd0
+#define R_CRL_PL0_THR_CNT         0xd4
+#define R_CRL_PL1_THR_CTRL        0xd8
+#define R_CRL_PL1_THR_CNT         0xdc
+#define R_CRL_PL2_THR_CTRL        0xe0
+#define R_CRL_PL2_THR_CNT         0xe4
+#define R_CRL_PL3_THR_CTRL        0xe8
+#define R_CRL_PL3_THR_CNT         0xfc
+#define R_CRL_GEM_TSU_REF_CTRL    0x100
+#define R_CRL_DLL_REF_CTRL        0x104
+#define R_CRL_AMS_REF_CTRL        0x108
+#define R_CRL_I2C0_REF_CTRL       0x120
+#define R_CRL_I2C1_REF_CTRL       0x124
+#define R_CRL_TIMESTAMP_REF_CTRL  0x128
+
+#define R_PMU_GLOBAL_GLOBAL_GEN_STORAGE0    0x30
+#define R_PMU_GLOBAL_PERS_GLOB_GEN_STORAGE7 0x6c
+
+#define R_PMU_GLOBAL_PWR_STATE              0x100
+
+#define R_CSU_IDCODE                        0x40
+
+#define R_IOU_SLCR_WDT_CLK_SEL            0x300
+#define R_IOU_SLCR_CAN_MIO_CTRL           0x304
+#define R_IOU_SLCR_GEM_CLK_CTRL           0x308
+#define R_IOU_SLCR_SDIO_CLK_CTRL          0x30c
+#define R_IOU_SLCR_CTRL_REG_SD	          0x310
+#define R_IOU_SLCR_SD_ITAPDLY	          0x314
+#define R_IOU_SLCR_SD_OTAPDLYSEL          0x318
+#define R_IOU_SLCR_SD_CONFIG_REG1         0x31c
+#define R_IOU_SLCR_SD_CONFIG_REG2         0x320
+#define R_IOU_SLCR_SD_CONFIG_REG3         0x324
+#define R_IOU_SLCR_SD_INITPRESET          0x328
+#define R_IOU_SLCR_SD_DSPPRESET	          0x32c
+#define R_IOU_SLCR_SD_HSPDPRESET          0x330
+#define R_IOU_SLCR_SD_SDR12PRESET         0x334
+#define R_IOU_SLCR_SD_SDR25PRESET         0x338
+#define R_IOU_SLCR_SD_SDR50PRSET          0x33c
+#define R_IOU_SLCR_SD_SDR104PRST          0x340
+#define R_IOU_SLCR_SD_DDR50PRESET         0x344
+#define R_IOU_SLCR_SD_MAXCUR1P8           0x34c
+#define R_IOU_SLCR_SD_MAXCUR3P0           0x350
+#define R_IOU_SLCR_SD_MAXCUR3P3           0x354
+#define R_IOU_SLCR_SD_DLL_CTRL            0x358
+#define R_IOU_SLCR_SD_CDN_CTRL            0x35c
+#define R_IOU_SLCR_GEM_CTRL               0x360
+#define R_IOU_SLCR_IOU_TTC_APB_CLK        0x380
+#define R_IOU_SLCR_IOU_TAPDLY_BYPASS      0x390
+#define R_IOU_SLCR_IOU_COHERENT_CTRL      0x400
+#define R_IOU_SLCR_VIDEO_PSS_CLK_SEL      0x404
+#define R_IOU_SLCR_IOU_INTERCONNECT_ROUTE 0x408
+#define R_IOU_SLCR_IOU_RAM_GEM0           0x500
+#define R_IOU_SLCR_IOU_RAM_GEM1           0x504
+#define R_IOU_SLCR_IOU_RAM_GEM2           0x508
+#define R_IOU_SLCR_IOU_RAM_GEM3           0x50c
+#define R_IOU_SLCR_IOU_RAM_SD0            0x510
+#define R_IOU_SLCR_IOU_RAM_SD1            0x514
+#define R_IOU_SLCR_IOU_RAM_CAN0           0x518
+#define R_IOU_SLCR_IOU_RAM_CAN1           0x51c
+#define R_IOU_SLCR_IOU_RAM_LQSPI          0x520
+#define R_IOU_SLCR_IOU_RAM_NAND           0x524
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  parent reply	other threads:[~2017-02-07 19:42 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-07 19:41 [RFC v2 0/6] zynqmp: Add forwarding of platform specific firmware calls Edgar E. Iglesias
2017-02-07 19:42 ` [RFC v2 1/6] xen/arm: traps: Reorder early overwrite of FID Edgar E. Iglesias
2017-02-13 22:06   ` Stefano Stabellini
2017-02-07 19:42 ` [RFC v2 2/6] xen/arm: Introduce platform_hvc Edgar E. Iglesias
2017-02-13 22:08   ` Stefano Stabellini
2017-07-31 21:30     ` Edgar E. Iglesias
2017-02-07 19:42 ` [RFC v2 3/6] xen/arm: Allow platform_hvc to handle guest SMC calls Edgar E. Iglesias
2017-02-07 20:38   ` Tamas K Lengyel
2017-02-07 20:51     ` Julien Grall
2017-02-08  0:24       ` Tamas K Lengyel
2017-02-08  8:31         ` Edgar E. Iglesias
2017-02-08 16:40           ` Tamas K Lengyel
2017-02-08 16:58             ` Julien Grall
2017-02-08 17:21               ` Tamas K Lengyel
2017-02-08 17:29               ` Edgar E. Iglesias
2017-02-08 19:40                 ` Edgar E. Iglesias
2017-02-08 20:15                   ` Tamas K Lengyel
2017-02-08 22:04                     ` Julien Grall
2017-02-08 23:28                       ` Tamas K Lengyel
2017-02-09  0:08                         ` Julien Grall
2017-02-09  1:20                           ` Stefano Stabellini
2017-02-09  9:12                             ` Edgar E. Iglesias
2017-02-09  9:27                               ` Edgar E. Iglesias
2017-02-09 18:22                                 ` Stefano Stabellini
2017-02-09 18:25                                   ` Tamas K Lengyel
2017-02-09 18:43                                     ` Stefano Stabellini
2017-02-09 19:32                                       ` Tamas K Lengyel
2017-07-31 22:23                                         ` Edgar E. Iglesias
2017-08-01 10:37                                           ` Julien Grall
2017-08-01 11:40                                             ` Edgar E. Iglesias
2017-02-09 16:46                           ` Volodymyr Babchuk
2017-02-09 18:11                           ` Tamas K Lengyel
2017-02-09 18:39                             ` Julien Grall
2017-02-09 19:42                               ` Tamas K Lengyel
2017-02-09 20:01                                 ` Edgar E. Iglesias
2017-02-09 20:36                                   ` Tamas K Lengyel
2017-02-09 14:46                       ` Edgar E. Iglesias
2017-02-07 19:42 ` [RFC v2 4/6] xen/arm: Introduce call_smcc64 Edgar E. Iglesias
2017-02-13 22:11   ` Stefano Stabellini
2017-02-07 19:42 ` Edgar E. Iglesias [this message]
2017-02-14  0:02   ` [RFC v2 5/6] xen/arm: zynqmp: Forward plaform specific firmware calls Stefano Stabellini
2017-02-17 18:47   ` Julien Grall
2017-02-07 19:42 ` [RFC v2 6/6] xen/arm: zynqmp: Remove blacklist of ZynqMP's PM node Edgar E. Iglesias
2017-02-14  0:03   ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1486496525-14637-6-git-send-email-edgar.iglesias@gmail.com \
    --to=edgar.iglesias@gmail.com \
    --cc=edgar.iglesias@xilinx.com \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).