Re: [PATCH v7 09/11] arm_mpam: add MPAM-Fb MSC firmware access support
From: Gavin Shan
Date: Tue Aug 04 2026 - 02:43:43 EST
Hi Andre,
On 8/1/26 3:03 AM, Andre Przywara wrote:
The Arm MPAM Firmware-backed (Fb) Profile document[1] describes an
alternative way of accessing the "Memory System Components" (MSC) in an
MPAM enabled system.
Normally the MSCs are MMIO mapped, but in some implementations this
might not be possible (MSC located outside of the local socket, MSC
mapped secure-only) or desirable (direct MMIO access too slow or needs
to be mediated through a control processor). MPAM-fb standardises a
protocol to abstract MSC accesses, building on the SCMI protocol.
Add functions that do an MSC read or write access by redirecting the
request through a firmware interface. For now this done via an ACPI
PCC shared memory and mailbox combination.
Since the protocol used is only a small subset of the full SCMI spec,
and the SCMI protocol has no full ACPI support anyway, open-code the
(simple) SCMI message generation, for just the fields we need.
[1] https://developer.arm.com/documentation/den0144/latest
Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
Reviewed-by: Jonathan Cameron <jonathan.cameron@xxxxxxxxxxxxxxxx>
Tested-by: Ritwick Sharma <ritwick.sharma@xxxxxxx>
---
drivers/resctrl/Makefile | 2 +-
drivers/resctrl/mpam_devices.c | 57 +++++++--
drivers/resctrl/mpam_fb.c | 209 ++++++++++++++++++++++++++++++++
drivers/resctrl/mpam_internal.h | 18 +++
include/linux/arm_mpam.h | 2 +-
5 files changed, 275 insertions(+), 13 deletions(-)
create mode 100644 drivers/resctrl/mpam_fb.c
[...]
diff --git a/drivers/resctrl/mpam_fb.c b/drivers/resctrl/mpam_fb.c
new file mode 100644
index 000000000000..61a91c6cec0a
--- /dev/null
+++ b/drivers/resctrl/mpam_fb.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2024-2026 Arm Ltd.
+
+#include <linux/arm_mpam.h>
+#include <linux/cleanup.h>
+#include <linux/errno.h>
+#include <linux/mailbox_client.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#include <acpi/pcc.h>
+#include <asm/mpam.h>
+
+#include "mpam_internal.h"
+
+#define MPAM_FB_PROTOCOL_ID 0x1a
+
+#define MPAM_PROTOCOL_VERSION_CMD 0x0
+#define MPAM_MSC_ATTRIBUTES_CMD 0x3
+#define MPAM_MSC_READ_CMD 0x4
+#define MPAM_MSC_WRITE_CMD 0x5
+
+#define MPAM_FB_ERR_SUCCESS 0
+#define MPAM_FB_ERR_NOT_SUPPORTED -1
+#define MPAM_FB_ERR_INVALID_PARAMETERS -2
+#define MPAM_FB_ERR_DENIED -3
+#define MPAM_FB_ERR_NOT_FOUND -4
+#define MPAM_FB_ERR_OUT_OF_RANGE -5
+#define MPAM_FB_ERR_BUSY -6
+#define MPAM_FB_ERR_COMMS_ERROR -7
+#define MPAM_FB_ERR_GENERIC_ERROR -8
+#define MPAM_FB_ERR_HW_ERROR -9
+#define MPAM_FB_ERR_PROTOCOL_ERROR -10
+#define MPAM_FB_ERR_IN_USE -11
+
+#define MPAM_MSC_PROT_ID_MASK GENMASK(17, 10)
+#define MPAM_MSC_TOKEN_MASK GENMASK(27, 18)
+
Why we're not using GENMASK_U32() since the operand the message is 32-bits dwords? :-)
+#define MPAM_FB_PROT_HEADER_LEN sizeof(u32)
+
+static atomic_t mpam_fb_token = ATOMIC_INIT(0);
+
+static void mpam_fb_build_version_message(unsigned int token,
+ void __iomem *msg_buf)
+{
+ struct acpi_pcct_ext_pcc_shared_memory __iomem *pcc_shmem = msg_buf;
+
+ /* .signature is filled by the platform */
+ writel_relaxed(PCC_CMD_COMPLETION_NOTIFY, &pcc_shmem->flags);
+ writel_relaxed(MPAM_FB_PROT_HEADER_LEN, &pcc_shmem->length);
+ writel_relaxed(MPAM_PROTOCOL_VERSION_CMD |
+ FIELD_PREP(MPAM_MSC_TOKEN_MASK, token) |
+ FIELD_PREP(MPAM_MSC_PROT_ID_MASK, MPAM_FB_PROTOCOL_ID),
+ &pcc_shmem->command);
+}
static inline void writel_relaxed(u32 value, volatile void __iomem *addr) { ...}
The input value would be 'unsigned long', which is converted to 'u32'. If GENMASK_U32()
is used to define MPAM_MSC_TOKEN_MASK and MPAM_MSC_PROT_ID_MASK, the unexpected conversion
can be avoided.
Thanks,
Gavin