// SPDX-License-Identifier: GPL-2.0 /* * AMD Platform Security Processor (PSP) Platform Access interface * * Copyright (C) 2023 Advanced Micro Devices, Inc. * * Author: Mario Limonciello <mario.limonciello@amd.com> * * Some of this code is adapted from drivers/i2c/busses/i2c-designware-amdpsp.c * developed by Jan Dabros <jsd@semihalf.com> and Copyright (C) 2022 Google Inc. *
*/
/* Expect mbox_cmd to be cleared and ready bit to be set by PSP */
expected = FIELD_PREP(PSP_CMDRESP_RESP, 1);
/* * Check for readiness of PSP mailbox in a tight loop in order to * process further as soon as command was consumed.
*/ return readl_poll_timeout(cmd, tmp, (tmp & expected), 0,
PSP_CMD_TIMEOUT_US);
}
int psp_check_platform_access_status(void)
{ struct psp_device *psp = psp_get_master_device();
if (!psp || !psp->platform_access_data) return -ENODEV;
if (!psp || !psp->platform_access_data) return -ENODEV;
pa_dev = psp->platform_access_data;
if (!pa_dev->vdata->cmdresp_reg || !pa_dev->vdata->cmdbuff_addr_lo_reg ||
!pa_dev->vdata->cmdbuff_addr_hi_reg) return -ENODEV;
cmd = psp->io_regs + pa_dev->vdata->cmdresp_reg;
lo = psp->io_regs + pa_dev->vdata->cmdbuff_addr_lo_reg;
hi = psp->io_regs + pa_dev->vdata->cmdbuff_addr_hi_reg;
mutex_lock(&pa_dev->mailbox_mutex);
if (check_recovery(cmd)) {
dev_dbg(psp->dev, "platform mailbox is in recovery\n");
ret = -EBUSY; goto unlock;
}
if (wait_cmd(cmd)) {
dev_dbg(psp->dev, "platform mailbox is not done processing command\n");
ret = -EBUSY; goto unlock;
}
/* * Fill mailbox with address of command-response buffer, which will be * used for sending i2c requests as well as reading status returned by * PSP. Use physical address of buffer, since PSP will map this region.
*/
req_addr = __psp_pa(req);
iowrite32(lower_32_bits(req_addr), lo);
iowrite32(upper_32_bits(req_addr), hi);
if (wait_cmd(cmd)) {
ret = -ETIMEDOUT; goto unlock;
}
/* Ensure it was triggered by this driver */ if (ioread32(lo) != lower_32_bits(req_addr) ||
ioread32(hi) != upper_32_bits(req_addr)) {
ret = -EBUSY; goto unlock;
}
/* * Read status from PSP. If status is non-zero, it indicates an error * occurred during "processing" of the command. * If status is zero, it indicates the command was "processed" * successfully, but the result of the command is in the payload. * Return both cases to the caller as -EIO to investigate.
*/
cmd_reg = ioread32(cmd); if (FIELD_GET(PSP_CMDRESP_STS, cmd_reg))
req->header.status = FIELD_GET(PSP_CMDRESP_STS, cmd_reg); if (req->header.status) {
ret = -EIO; goto unlock;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.