|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 5/6] xen/arm: zynqmp: implement zynqmp_eemi
On Tue, 28 Aug 2018, Julien Grall wrote:
> Hi Stefano,
>
> On 11/08/18 01:01, Stefano Stabellini wrote:
> > From: "Edgar E. Iglesias" <edgar.iglesias@xxxxxxxxxx>
> >
> > From: Edgar E. Iglesias <edgar.iglesias@xxxxxxxxxx>
> >
> > zynqmp_eemi uses the defined functions and structs to decide whether to
> > make a call to the firmware, or to simply return a predefined value.
> >
> > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xxxxxxxxxx>
> > Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx>
> > ---
> > xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 143
> > +++++++++++++++++++++++++++-
> > 1 file changed, 142 insertions(+), 1 deletion(-)
> >
> > diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
> > b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
> > index 62cc15c..1dbdf04 100644
> > --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
> > +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c
> > @@ -808,7 +808,148 @@ static bool domain_has_mmio_access(struct domain *d,
> > bool zynqmp_eemi(struct cpu_user_regs *regs)
> > {
> > - return false;
> > + struct arm_smccc_res res;
> > + bool is_mmio_write = false;
> > + uint32_t fid = get_user_reg(regs, 0);
> > + uint32_t nodeid = get_user_reg(regs, 1);
> > + unsigned int pm_fn = fid & 0xFFFF;
>
> Here you will receive all the function ID for the SIP subsystem. Can you
> confirm the EEMI can be accessed from both SMC32 and SMC64 convention?
Yep
> > + enum pm_ret_status 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.
>
> Why WFI specifically? The guest should suspend using PSCI normally.
Just a limitation of the comment. I'll a mention PSCI.
> > + */
> > + case PM_SELF_SUSPEND:
> > + ret = XST_PM_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, nodeid) )
> > + {
> > + gprintk(XENLOG_WARNING,
> > + "zynqmp-pm: fn=%u No access to node %u\n", pm_fn,
> > nodeid);
> > + ret = XST_PM_NO_ACCESS;
> > + goto done;
> > + }
> > + goto forward_to_fw;
> > +
> > + case PM_RESET_ASSERT:
> > + case PM_RESET_GET_STATUS:
> > + if ( !domain_has_reset_access(current->domain, nodeid) )
> > + {
> > + gprintk(XENLOG_WARNING,
> > + "zynqmp-pm: fn=%u No access to reset %u\n", pm_fn,
> > nodeid);
> > + ret = XST_PM_NO_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_TRUSTZONE_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:
> > + {
> > + uint32_t mask = get_user_reg(regs, 1) >> 32;
>
> NIT: newline.
OK
>
> > + if ( !domain_has_mmio_access(current->domain,
> > + is_mmio_write,
> > + nodeid, &mask) )
> > + {
> > + gprintk(XENLOG_WARNING,
> > + "eemi: fn=%u No access to MMIO %s %u\n",
> > + pm_fn, is_mmio_write ? "write" : "read", nodeid);
> > + ret = XST_PM_NO_ACCESS;
> > + goto done;
> > + }
> > + set_user_reg(regs, 1, ((uint64_t)mask << 32) | nodeid);
>
> Can you define 32 in a macro?
Yes, I'll do
> > + goto forward_to_fw;
> > + }
> > +
> > + /* Exclusive to the hardware domain. */
> > + case PM_INIT:
> > + case PM_SET_CONFIGURATION:
> > + case PM_FPGA_LOAD:
> > + case PM_FPGA_GET_STATUS:
> > + case PM_SECURE_SHA:
> > + case PM_SECURE_RSA:
> > + case PM_PINCTRL_SET_FUNCTION:
> > + case PM_PINCTRL_REQUEST:
> > + case PM_PINCTRL_RELEASE:
> > + case PM_PINCTRL_GET_FUNCTION:
> > + case PM_PINCTRL_CONFIG_PARAM_GET:
> > + case PM_PINCTRL_CONFIG_PARAM_SET:
> > + case PM_IOCTL:
> > + case PM_QUERY_DATA:
> > + case PM_CLOCK_ENABLE:
> > + case PM_CLOCK_DISABLE:
> > + case PM_CLOCK_GETSTATE:
> > + case PM_CLOCK_GETDIVIDER:
> > + case PM_CLOCK_SETDIVIDER:
> > + case PM_CLOCK_SETRATE:
> > + case PM_CLOCK_GETRATE:
> > + case PM_CLOCK_SETPARENT:
> > + case PM_CLOCK_GETPARENT:
> > + if ( !is_hardware_domain(current->domain) )
> > + {
> > + gprintk(XENLOG_WARNING, "eemi: fn=%u No access", pm_fn);
> > + ret = XST_PM_NO_ACCESS;
> > + goto done;
> > + }
> > + goto forward_to_fw;
> > +
> > + /* These calls are never allowed. */
> > + case PM_SYSTEM_SHUTDOWN:
> > + ret = XST_PM_NO_ACCESS;
> > + goto done;
> > +
> > + default:
> > + gprintk(XENLOG_WARNING, "zynqmp-pm: Unhandled PM Call: %u\n", fid);
> > + return false;
>
> The functions COUNT, UUID, REVISION mandated by the SMCCC are missing here.
They are just above. They are defined as ZYNQMP_SIP_SVC_CALL_COUNT,
ZYNQMP_SIP_SVC_UID and ZYNQMP_SIP_SVC_VERSION. They are set to always
forward to firmware.
> > + }
> > +
> > +forward_to_fw:
> > + arm_smccc_1_1_smc(get_user_reg(regs, 0),
> > + get_user_reg(regs, 1),
> > + get_user_reg(regs, 2),
> > + get_user_reg(regs, 3),
> > + get_user_reg(regs, 4),
> > + get_user_reg(regs, 5),
> > + get_user_reg(regs, 6),
> > + get_user_reg(regs, 7),
> > + &res);
> > +
> > + set_user_reg(regs, 0, res.a0);
> > + set_user_reg(regs, 1, res.a1);
> > + set_user_reg(regs, 2, res.a2);
> > + set_user_reg(regs, 3, res.a3);
> > + return true;
> > +
> > +done:
> > + set_user_reg(regs, 0, ret);
> > + return true;
> > }
> > /*
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |