From 72bc04b8744c8b2756cbf115a88bc48fbde57c6b Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:03 +0200 Subject: [PATCH 1/6] arm: apple: rtkit: Add support for AP power & syslogs This is required for MTP to work properly Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/include/asm/arch-apple/rtkit.h | 2 + arch/arm/mach-apple/rtkit.c | 146 ++++++++++++++++++------ 2 files changed, 111 insertions(+), 37 deletions(-) diff --git a/arch/arm/include/asm/arch-apple/rtkit.h b/arch/arm/include/asm/arch-apple/rtkit.h index eff18ddb9d2..b795215feb7 100644 --- a/arch/arm/include/asm/arch-apple/rtkit.h +++ b/arch/arm/include/asm/arch-apple/rtkit.h @@ -26,4 +26,6 @@ struct apple_rtkit *apple_rtkit_init(struct mbox_chan *chan, void *cookie, apple_rtkit_shmem_destroy shmem_destroy); void apple_rtkit_free(struct apple_rtkit *rtk); int apple_rtkit_boot(struct apple_rtkit *rtk); +int apple_rtkit_set_ap_power(struct apple_rtkit *rtk, int pwrstate); +int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout); int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate); diff --git a/arch/arm/mach-apple/rtkit.c b/arch/arm/mach-apple/rtkit.c index b8f4771e5e7..433ffb259ee 100644 --- a/arch/arm/mach-apple/rtkit.c +++ b/arch/arm/mach-apple/rtkit.c @@ -36,6 +36,7 @@ #define APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE 6 #define APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK 7 +#define APPLE_RTKIT_MGMT_SET_AP_PWR_STATE 11 #define APPLE_RTKIT_MGMT_EPMAP 8 #define APPLE_RTKIT_MGMT_EPMAP_LAST BIT(51) @@ -64,6 +65,9 @@ struct apple_rtkit { struct apple_rtkit_buffer syslog_buffer; struct apple_rtkit_buffer crashlog_buffer; struct apple_rtkit_buffer ioreport_buffer; + + int iop_pwr; + int ap_pwr; }; struct apple_rtkit *apple_rtkit_init(struct mbox_chan *chan, void *cookie, @@ -150,6 +154,75 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap return 0; } +int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout) +{ + struct apple_mbox_msg msg; + int ret; + int endpoint; + int msgtype; + + ret = mbox_recv(rtk->chan, &msg, timeout); + if (ret < 0) + return ret; + + endpoint = msg.msg1; + msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0); + + if (endpoint == APPLE_RTKIT_EP_CRASHLOG || + endpoint == APPLE_RTKIT_EP_SYSLOG || + endpoint == APPLE_RTKIT_EP_IOREPORT) { + if (msgtype == APPLE_RTKIT_BUFFER_REQUEST) { + ret = rtkit_handle_buf_req(rtk, endpoint, &msg); + if (ret < 0) + return ret; + return 0; + } + } + + if (endpoint == APPLE_RTKIT_EP_IOREPORT) { + // these two messages have to be ack-ed for proper startup + if (msgtype == 0xc || msgtype == 0x8) { + ret = mbox_send(rtk->chan, &msg); + if (ret < 0) + return ret; + return 0; + } + } + + if (endpoint == APPLE_RTKIT_EP_SYSLOG) { + /* Ignore init */ + if (msgtype == 0x8) + return 0; + + /* Ack logs */ + if (msgtype == 0x5) { + ret = mbox_send(rtk->chan, &msg); + if (ret < 0) + return ret; + return 0; + } + } + + if (endpoint != APPLE_RTKIT_EP_MGMT) { + printf("%s: unexpected endpoint %d\n", __func__, endpoint); + return -EINVAL; + } + + switch (msgtype) { + case APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK: + rtk->iop_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0); + return 0; + case APPLE_RTKIT_MGMT_SET_AP_PWR_STATE: + rtk->ap_pwr = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0); + return 0; + default: + printf("%s: unexpected message type %d\n", __func__, msgtype); + + /* Just ignore it */ + return 0; + } +} + int apple_rtkit_boot(struct apple_rtkit *rtk) { struct apple_mbox_msg msg; @@ -157,7 +230,7 @@ int apple_rtkit_boot(struct apple_rtkit *rtk) int nendpoints = 0; int endpoint; int min_ver, max_ver, want_ver; - int msgtype, pwrstate; + int msgtype; u64 reply; u32 bitmap, base; int i, ret; @@ -276,46 +349,37 @@ wait_epmap: return ret; } - pwrstate = APPLE_RTKIT_PWR_STATE_SLEEP; - while (pwrstate != APPLE_RTKIT_PWR_STATE_ON) { - ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US); + rtk->iop_pwr = APPLE_RTKIT_PWR_STATE_SLEEP; + rtk->ap_pwr = APPLE_RTKIT_PWR_STATE_QUIESCED; + + while (rtk->iop_pwr != APPLE_RTKIT_PWR_STATE_ON) { + ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US); if (ret < 0) return ret; + } - endpoint = msg.msg1; - msgtype = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg.msg0); + return 0; +} - if (endpoint == APPLE_RTKIT_EP_CRASHLOG || - endpoint == APPLE_RTKIT_EP_SYSLOG || - endpoint == APPLE_RTKIT_EP_IOREPORT) { - if (msgtype == APPLE_RTKIT_BUFFER_REQUEST) { - ret = rtkit_handle_buf_req(rtk, endpoint, &msg); - if (ret < 0) - return ret; - continue; - } - } +int apple_rtkit_set_ap_power(struct apple_rtkit *rtk, int pwrstate) +{ + struct apple_mbox_msg msg; + int ret; - if (endpoint == APPLE_RTKIT_EP_IOREPORT) { - // these two messages have to be ack-ed for proper startup - if (msgtype == 0xc || msgtype == 0x8) { - ret = mbox_send(rtk->chan, &msg); - if (ret < 0) - return ret; - continue; - } - } + if (rtk->ap_pwr == pwrstate) + return 0; - if (endpoint != APPLE_RTKIT_EP_MGMT) { - printf("%s: unexpected endpoint %d\n", __func__, endpoint); - return -EINVAL; - } - if (msgtype != APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK) { - printf("%s: unexpected message type %d\n", __func__, msgtype); - return -EINVAL; - } + msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE) | + FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate); + msg.msg1 = APPLE_RTKIT_EP_MGMT; + ret = mbox_send(rtk->chan, &msg); + if (ret < 0) + return ret; - pwrstate = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0); + while (rtk->ap_pwr != pwrstate) { + ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US); + if (ret < 0) + return ret; } return 0; @@ -326,6 +390,12 @@ int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate) struct apple_mbox_msg msg; int ret; + if (rtk->ap_pwr != APPLE_RTKIT_PWR_STATE_QUIESCED) { + ret = apple_rtkit_set_ap_power(rtk, APPLE_RTKIT_PWR_STATE_QUIESCED); + if (ret < 0) + return ret; + } + msg.msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE) | FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, pwrstate); msg.msg1 = APPLE_RTKIT_EP_MGMT; @@ -333,9 +403,11 @@ int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate) if (ret < 0) return ret; - ret = mbox_recv(rtk->chan, &msg, TIMEOUT_1SEC_US); - if (ret < 0) - return ret; + while (rtk->iop_pwr != pwrstate) { + ret = apple_rtkit_poll(rtk, TIMEOUT_1SEC_US); + if (ret < 0) + return ret; + } return 0; } From 89cb15788a16f2568083d984c547ff41c56a2d68 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:04 +0200 Subject: [PATCH 2/6] arm: apple: rtkit: Add default buffer handlers For devices without specific buffer methods, just assume we can give them raw memory pointers when they request a buffer. Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/rtkit.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-apple/rtkit.c b/arch/arm/mach-apple/rtkit.c index 433ffb259ee..5e8e282ec0e 100644 --- a/arch/arm/mach-apple/rtkit.c +++ b/arch/arm/mach-apple/rtkit.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #define APPLE_RTKIT_EP_MGMT 0 @@ -97,6 +98,13 @@ void apple_rtkit_free(struct apple_rtkit *rtk) rtk->shmem_destroy(rtk->cookie, &rtk->crashlog_buffer); if (rtk->ioreport_buffer.buffer) rtk->shmem_destroy(rtk->cookie, &rtk->ioreport_buffer); + } else { + if (rtk->syslog_buffer.buffer) + free(rtk->syslog_buffer.buffer); + if (rtk->crashlog_buffer.buffer) + free(rtk->crashlog_buffer.buffer); + if (rtk->ioreport_buffer.buffer) + free(rtk->ioreport_buffer.buffer); } free(rtk); } @@ -131,7 +139,7 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0); buf->size = num_4kpages << 12; - buf->is_mapped = false; + buf->is_mapped = !!buf->dva; if (rtk->shmem_setup) { ret = rtk->shmem_setup(rtk->cookie, buf); @@ -140,6 +148,12 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap endpoint); return ret; } + } else if (!buf->is_mapped){ + buf->buffer = memalign(SZ_16K, ALIGN(buf->size, SZ_16K)); + if (!buf->buffer) + return -ENOMEM; + + buf->dva = (u64)buf->buffer; } if (!buf->is_mapped) { From 7bac7f5f012f4990ac28116839043cf588499e3a Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:05 +0200 Subject: [PATCH 3/6] arm: apple: rtkit: Add a generic RTKit helper driver This driver handles the MTP ASC coprocessor, which does not need any special handling on the RTKit side and communicates out-of-band. Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/include/asm/arch-apple/rtkit.h | 2 + arch/arm/mach-apple/Makefile | 1 + arch/arm/mach-apple/rtkit_helper.c | 97 +++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 arch/arm/mach-apple/rtkit_helper.c diff --git a/arch/arm/include/asm/arch-apple/rtkit.h b/arch/arm/include/asm/arch-apple/rtkit.h index b795215feb7..1b6c6ccd821 100644 --- a/arch/arm/include/asm/arch-apple/rtkit.h +++ b/arch/arm/include/asm/arch-apple/rtkit.h @@ -29,3 +29,5 @@ int apple_rtkit_boot(struct apple_rtkit *rtk); int apple_rtkit_set_ap_power(struct apple_rtkit *rtk, int pwrstate); int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout); int apple_rtkit_shutdown(struct apple_rtkit *rtk, int pwrstate); + +int apple_rtkit_helper_poll(struct udevice *dev, ulong timeout); diff --git a/arch/arm/mach-apple/Makefile b/arch/arm/mach-apple/Makefile index 50b465b9473..d79a3a69592 100644 --- a/arch/arm/mach-apple/Makefile +++ b/arch/arm/mach-apple/Makefile @@ -3,4 +3,5 @@ obj-y += board.o obj-y += lowlevel_init.o obj-y += rtkit.o +obj-$(CONFIG_APPLE_MTP_KEYB) += rtkit_helper.o obj-$(CONFIG_NVME_APPLE) += sart.o diff --git a/arch/arm/mach-apple/rtkit_helper.c b/arch/arm/mach-apple/rtkit_helper.c new file mode 100644 index 00000000000..3b755008195 --- /dev/null +++ b/arch/arm/mach-apple/rtkit_helper.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Copyright The Asahi Linux Contributors + */ + +#include +#include +#include +#include + +#include +#include +#include + +/* ASC registers */ +#define REG_CPU_CTRL 0x0044 +#define REG_CPU_CTRL_RUN BIT(4) + +struct rtkit_helper_priv { + void *asc; /* ASC registers */ + struct mbox_chan chan; + struct apple_rtkit *rtk; +}; + +static int rtkit_helper_probe(struct udevice *dev) +{ + struct rtkit_helper_priv *priv = dev_get_priv(dev); + u32 ctrl; + int ret; + + priv->asc = dev_read_addr_ptr(dev); + if (!priv->asc) + return -EINVAL; + + ret = mbox_get_by_index(dev, 0, &priv->chan); + if (ret < 0) + return ret; + + ctrl = readl(priv->asc + REG_CPU_CTRL); + writel(ctrl | REG_CPU_CTRL_RUN, priv->asc + REG_CPU_CTRL); + + priv->rtk = apple_rtkit_init(&priv->chan, priv, NULL, NULL); + if (!priv->rtk) + return -ENOMEM; + + ret = apple_rtkit_boot(priv->rtk); + if (ret < 0) { + printf("%s: Helper apple_rtkit_boot returned: %d\n", __func__, ret); + return ret; + } + + ret = apple_rtkit_set_ap_power(priv->rtk, APPLE_RTKIT_PWR_STATE_ON); + if (ret < 0) { + printf("%s: Helper apple_rtkit_set_ap_power returned: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static int rtkit_helper_remove(struct udevice *dev) +{ + struct rtkit_helper_priv *priv = dev_get_priv(dev); + u32 ctrl; + + apple_rtkit_shutdown(priv->rtk, APPLE_RTKIT_PWR_STATE_QUIESCED); + + ctrl = readl(priv->asc + REG_CPU_CTRL); + writel(ctrl & ~REG_CPU_CTRL_RUN, priv->asc + REG_CPU_CTRL); + + apple_rtkit_free(priv->rtk); + priv->rtk = NULL; + + return 0; +} + +int apple_rtkit_helper_poll(struct udevice *dev, ulong timeout) +{ + struct rtkit_helper_priv *priv = dev_get_priv(dev); + + return apple_rtkit_poll(priv->rtk, timeout); +} + +static const struct udevice_id rtkit_helper_ids[] = { + { .compatible = "apple,rtk-helper-asc4" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(rtkit_helper) = { + .name = "rtkit_helper", + .id = UCLASS_MISC, + .of_match = rtkit_helper_ids, + .priv_auto = sizeof(struct rtkit_helper_priv), + .probe = rtkit_helper_probe, + .remove = rtkit_helper_remove, + .flags = DM_FLAG_OS_PREPARE, +}; From 082789a4f7a1a7bac46ef75f98acf93ee8bfe837 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:06 +0200 Subject: [PATCH 4/6] arm: apple: rtkit: Add OSLog buffer support This will work for u-boot itself, but needs a special workaround in the MTP driver for Linux handoff to work. Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/rtkit.c | 69 ++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-apple/rtkit.c b/arch/arm/mach-apple/rtkit.c index 5e8e282ec0e..d294ee09350 100644 --- a/arch/arm/mach-apple/rtkit.c +++ b/arch/arm/mach-apple/rtkit.c @@ -19,6 +19,7 @@ #define APPLE_RTKIT_EP_SYSLOG 2 #define APPLE_RTKIT_EP_DEBUG 3 #define APPLE_RTKIT_EP_IOREPORT 4 +#define APPLE_RTKIT_EP_OSLOG 8 #define APPLE_RTKIT_EP_TRACEKIT 10 /* Messages for management endpoint. */ @@ -47,6 +48,11 @@ #define APPLE_RTKIT_MGMT_EPMAP_REPLY 8 #define APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE BIT(0) +#define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56) +#define APPLE_RTKIT_OSLOG_BUFFER_REQUEST 1 +#define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36) +#define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0) + #define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11 #define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12 @@ -66,6 +72,7 @@ struct apple_rtkit { struct apple_rtkit_buffer syslog_buffer; struct apple_rtkit_buffer crashlog_buffer; struct apple_rtkit_buffer ioreport_buffer; + struct apple_rtkit_buffer oslog_buffer; int iop_pwr; int ap_pwr; @@ -98,6 +105,8 @@ void apple_rtkit_free(struct apple_rtkit *rtk) rtk->shmem_destroy(rtk->cookie, &rtk->crashlog_buffer); if (rtk->ioreport_buffer.buffer) rtk->shmem_destroy(rtk->cookie, &rtk->ioreport_buffer); + if (rtk->oslog_buffer.buffer) + rtk->shmem_destroy(rtk->cookie, &rtk->oslog_buffer); } else { if (rtk->syslog_buffer.buffer) free(rtk->syslog_buffer.buffer); @@ -105,6 +114,8 @@ void apple_rtkit_free(struct apple_rtkit *rtk) free(rtk->crashlog_buffer.buffer); if (rtk->ioreport_buffer.buffer) free(rtk->ioreport_buffer.buffer); + if (rtk->oslog_buffer.buffer) + free(rtk->oslog_buffer.buffer); } free(rtk); } @@ -112,16 +123,8 @@ void apple_rtkit_free(struct apple_rtkit *rtk) static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct apple_mbox_msg *msg) { struct apple_rtkit_buffer *buf; - size_t num_4kpages; int ret; - num_4kpages = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg->msg0); - - if (num_4kpages == 0) { - printf("%s: unexpected request for buffer without size\n", __func__); - return -1; - } - switch (endpoint) { case APPLE_RTKIT_EP_CRASHLOG: buf = &rtk->crashlog_buffer; @@ -132,13 +135,31 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap case APPLE_RTKIT_EP_IOREPORT: buf = &rtk->ioreport_buffer; break; + case APPLE_RTKIT_EP_OSLOG: + buf = &rtk->oslog_buffer; + break; default: printf("%s: unexpected endpoint %d\n", __func__, endpoint); return -1; } + switch (endpoint) { + case APPLE_RTKIT_EP_OSLOG: + buf->size = FIELD_GET(APPLE_RTKIT_OSLOG_SIZE, msg->msg0); + buf->dva = FIELD_GET(APPLE_RTKIT_OSLOG_IOVA, msg->msg0 << 12); + break; + default: + buf->size = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg->msg0) << 12; + buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0); + break; + } + + if (buf->size == 0) { + printf("%s: unexpected request for buffer without size\n", __func__); + return -1; + } + buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0); - buf->size = num_4kpages << 12; buf->is_mapped = !!buf->dva; if (rtk->shmem_setup) { @@ -157,10 +178,18 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap } if (!buf->is_mapped) { - msg->msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, APPLE_RTKIT_BUFFER_REQUEST) | - FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, num_4kpages) | - FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, buf->dva); - msg->msg1 = endpoint; + /* oslog uses different fields */ + if (endpoint == APPLE_RTKIT_EP_OSLOG) { + msg->msg0 = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE, + APPLE_RTKIT_OSLOG_BUFFER_REQUEST); + msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buf->size); + msg->msg0 |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA, buf->dva >> 12); + } else { + msg->msg0 = FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, + APPLE_RTKIT_BUFFER_REQUEST); + msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, buf->size >> 12); + msg->msg0 |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA, buf->dva); + } return mbox_send(rtk->chan, msg); } @@ -193,6 +222,20 @@ int apple_rtkit_poll(struct apple_rtkit *rtk, ulong timeout) } } + if (endpoint == APPLE_RTKIT_EP_OSLOG) { + msgtype = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg.msg0); + + if (msgtype == APPLE_RTKIT_OSLOG_BUFFER_REQUEST) { + ret = rtkit_handle_buf_req(rtk, endpoint, &msg); + if (ret < 0) + return ret; + return 0; + } else { + /* Ignore */ + return 0; + } + } + if (endpoint == APPLE_RTKIT_EP_IOREPORT) { // these two messages have to be ack-ed for proper startup if (msgtype == 0xc || msgtype == 0x8) { From fe593cc8ed9b9616eca9d094be1b1557824dcea4 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:07 +0200 Subject: [PATCH 5/6] arm: apple: rtkit: Add endpoint field to buffers To be used for special-case oslog support in rtkit-helper. Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/include/asm/arch-apple/rtkit.h | 1 + arch/arm/mach-apple/rtkit.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/include/asm/arch-apple/rtkit.h b/arch/arm/include/asm/arch-apple/rtkit.h index 1b6c6ccd821..4b11e2a72dc 100644 --- a/arch/arm/include/asm/arch-apple/rtkit.h +++ b/arch/arm/include/asm/arch-apple/rtkit.h @@ -12,6 +12,7 @@ struct apple_rtkit_buffer { u64 dva; size_t size; bool is_mapped; + int endpoint; }; typedef int (*apple_rtkit_shmem_setup)(void *cookie, diff --git a/arch/arm/mach-apple/rtkit.c b/arch/arm/mach-apple/rtkit.c index d294ee09350..f3561543a35 100644 --- a/arch/arm/mach-apple/rtkit.c +++ b/arch/arm/mach-apple/rtkit.c @@ -161,6 +161,7 @@ static int rtkit_handle_buf_req(struct apple_rtkit *rtk, int endpoint, struct ap buf->dva = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg->msg0); buf->is_mapped = !!buf->dva; + buf->endpoint = endpoint; if (rtk->shmem_setup) { ret = rtk->shmem_setup(rtk->cookie, buf); From 4a55e7f0311df145662831576bbe0ed2113227ce Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 20 Apr 2025 13:58:08 +0200 Subject: [PATCH 6/6] arm: apple: rtkit: Support allocating OSLog out of SRAM in helper The new OSLog region in MTP (firmware 13.3+) persists on handoff to Linux. To avoid having to come up with some weird DART handoff or DAPF tricks, let's just steal some of the coprocessor's dedicated SRAM. This keeps it happy and Linux doesn't need any special handoff then. Signed-off-by: Hector Martin Signed-off-by: Mark Kettenis --- arch/arm/mach-apple/rtkit_helper.c | 50 +++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-apple/rtkit_helper.c b/arch/arm/mach-apple/rtkit_helper.c index 3b755008195..b7d60e15700 100644 --- a/arch/arm/mach-apple/rtkit_helper.c +++ b/arch/arm/mach-apple/rtkit_helper.c @@ -16,12 +16,60 @@ #define REG_CPU_CTRL 0x0044 #define REG_CPU_CTRL_RUN BIT(4) +#define APPLE_RTKIT_EP_OSLOG 8 + struct rtkit_helper_priv { void *asc; /* ASC registers */ struct mbox_chan chan; struct apple_rtkit *rtk; + bool sram_stolen; }; +static int shmem_setup(void *cookie, struct apple_rtkit_buffer *buf) { + struct udevice *dev = cookie; + struct rtkit_helper_priv *priv = dev_get_priv(dev); + + if (!buf->is_mapped) { + /* + * Special case: The OSLog buffer on MTP persists on Linux handoff. + * Steal some SRAM instead of putting this in DRAM, so we don't + * have to hand off DART/DAPF mappings. + */ + if (buf->endpoint == APPLE_RTKIT_EP_OSLOG) { + if (priv->sram_stolen) { + printf("%s: Tried to map more than one OSLog buffer out of SRAM\n", + __func__); + } else { + fdt_size_t size; + fdt_addr_t addr; + + addr = dev_read_addr_size_name(dev, "sram", &size); + + if (addr != FDT_ADDR_T_NONE) { + buf->dva = ALIGN_DOWN(addr + size - buf->size, SZ_16K); + priv->sram_stolen = true; + + return 0; + } else { + printf("%s: No SRAM, falling back to DRAM\n", __func__); + } + } + } + + buf->buffer = memalign(SZ_16K, ALIGN(buf->size, SZ_16K)); + if (!buf->buffer) + return -ENOMEM; + + buf->dva = (u64)buf->buffer; + } + return 0; +} + +static void shmem_destroy(void *cookie, struct apple_rtkit_buffer *buf) { + if (buf->buffer) + free(buf->buffer); +} + static int rtkit_helper_probe(struct udevice *dev) { struct rtkit_helper_priv *priv = dev_get_priv(dev); @@ -39,7 +87,7 @@ static int rtkit_helper_probe(struct udevice *dev) ctrl = readl(priv->asc + REG_CPU_CTRL); writel(ctrl | REG_CPU_CTRL_RUN, priv->asc + REG_CPU_CTRL); - priv->rtk = apple_rtkit_init(&priv->chan, priv, NULL, NULL); + priv->rtk = apple_rtkit_init(&priv->chan, dev, shmem_setup, shmem_destroy); if (!priv->rtk) return -ENOMEM;