[PATCH 1/6] arm: apple: rtkit: Add support for AP power & syslogs

Mark Kettenis kettenis at openbsd.org
Sun Apr 20 13:58:03 CEST 2025


From: Hector Martin <marcan at marcan.st>

This is required for MTP to work properly

Signed-off-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Mark Kettenis <kettenis at openbsd.org>
---
 arch/arm/include/asm/arch-apple/rtkit.h |   2 +
 arch/arm/mach-apple/rtkit.c             | 148 ++++++++++++++++++------
 2 files changed, 112 insertions(+), 38 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);
-
-		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;
-			}
-		}
+	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;
-				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_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;
-		}
+	if (rtk->ap_pwr == pwrstate)
+		return 0;
 
-		pwrstate = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg.msg0);
+	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;
+
+	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;
 }
-- 
2.49.0



More information about the U-Boot mailing list