cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtkit.c (24341B)


      1// SPDX-License-Identifier: GPL-2.0-only OR MIT
      2/*
      3 * Apple RTKit IPC library
      4 * Copyright (C) The Asahi Linux Contributors
      5 */
      6
      7#include "rtkit-internal.h"
      8
      9enum {
     10	APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */
     11	APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */
     12	APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */
     13	APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */
     14};
     15
     16enum {
     17	APPLE_RTKIT_EP_MGMT = 0,
     18	APPLE_RTKIT_EP_CRASHLOG = 1,
     19	APPLE_RTKIT_EP_SYSLOG = 2,
     20	APPLE_RTKIT_EP_DEBUG = 3,
     21	APPLE_RTKIT_EP_IOREPORT = 4,
     22	APPLE_RTKIT_EP_OSLOG = 8,
     23};
     24
     25#define APPLE_RTKIT_MGMT_TYPE GENMASK_ULL(59, 52)
     26
     27enum {
     28	APPLE_RTKIT_MGMT_HELLO = 1,
     29	APPLE_RTKIT_MGMT_HELLO_REPLY = 2,
     30	APPLE_RTKIT_MGMT_STARTEP = 5,
     31	APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE = 6,
     32	APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK = 7,
     33	APPLE_RTKIT_MGMT_EPMAP = 8,
     34	APPLE_RTKIT_MGMT_EPMAP_REPLY = 8,
     35	APPLE_RTKIT_MGMT_SET_AP_PWR_STATE = 0xb,
     36	APPLE_RTKIT_MGMT_SET_AP_PWR_STATE_ACK = 0xb,
     37};
     38
     39#define APPLE_RTKIT_MGMT_HELLO_MINVER GENMASK_ULL(15, 0)
     40#define APPLE_RTKIT_MGMT_HELLO_MAXVER GENMASK_ULL(31, 16)
     41
     42#define APPLE_RTKIT_MGMT_EPMAP_LAST   BIT_ULL(51)
     43#define APPLE_RTKIT_MGMT_EPMAP_BASE   GENMASK_ULL(34, 32)
     44#define APPLE_RTKIT_MGMT_EPMAP_BITMAP GENMASK_ULL(31, 0)
     45
     46#define APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE BIT_ULL(0)
     47
     48#define APPLE_RTKIT_MGMT_STARTEP_EP   GENMASK_ULL(39, 32)
     49#define APPLE_RTKIT_MGMT_STARTEP_FLAG BIT_ULL(1)
     50
     51#define APPLE_RTKIT_MGMT_PWR_STATE GENMASK_ULL(15, 0)
     52
     53#define APPLE_RTKIT_CRASHLOG_CRASH 1
     54
     55#define APPLE_RTKIT_BUFFER_REQUEST	1
     56#define APPLE_RTKIT_BUFFER_REQUEST_SIZE GENMASK_ULL(51, 44)
     57#define APPLE_RTKIT_BUFFER_REQUEST_IOVA GENMASK_ULL(41, 0)
     58
     59#define APPLE_RTKIT_SYSLOG_TYPE GENMASK_ULL(59, 52)
     60
     61#define APPLE_RTKIT_SYSLOG_LOG 5
     62
     63#define APPLE_RTKIT_SYSLOG_INIT	     8
     64#define APPLE_RTKIT_SYSLOG_N_ENTRIES GENMASK_ULL(7, 0)
     65#define APPLE_RTKIT_SYSLOG_MSG_SIZE  GENMASK_ULL(31, 24)
     66
     67#define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56)
     68#define APPLE_RTKIT_OSLOG_INIT	1
     69#define APPLE_RTKIT_OSLOG_ACK	3
     70
     71#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11
     72#define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12
     73
     74struct apple_rtkit_msg {
     75	struct completion *completion;
     76	struct apple_mbox_msg mbox_msg;
     77};
     78
     79struct apple_rtkit_rx_work {
     80	struct apple_rtkit *rtk;
     81	u8 ep;
     82	u64 msg;
     83	struct work_struct work;
     84};
     85
     86bool apple_rtkit_is_running(struct apple_rtkit *rtk)
     87{
     88	if (rtk->crashed)
     89		return false;
     90	if ((rtk->iop_power_state & 0xff) != APPLE_RTKIT_PWR_STATE_ON)
     91		return false;
     92	if ((rtk->ap_power_state & 0xff) != APPLE_RTKIT_PWR_STATE_ON)
     93		return false;
     94	return true;
     95}
     96EXPORT_SYMBOL_GPL(apple_rtkit_is_running);
     97
     98bool apple_rtkit_is_crashed(struct apple_rtkit *rtk)
     99{
    100	return rtk->crashed;
    101}
    102EXPORT_SYMBOL_GPL(apple_rtkit_is_crashed);
    103
    104static void apple_rtkit_management_send(struct apple_rtkit *rtk, u8 type,
    105					u64 msg)
    106{
    107	msg &= ~APPLE_RTKIT_MGMT_TYPE;
    108	msg |= FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, type);
    109	apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_MGMT, msg, NULL, false);
    110}
    111
    112static void apple_rtkit_management_rx_hello(struct apple_rtkit *rtk, u64 msg)
    113{
    114	u64 reply;
    115
    116	int min_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MINVER, msg);
    117	int max_ver = FIELD_GET(APPLE_RTKIT_MGMT_HELLO_MAXVER, msg);
    118	int want_ver = min(APPLE_RTKIT_MAX_SUPPORTED_VERSION, max_ver);
    119
    120	dev_dbg(rtk->dev, "RTKit: Min ver %d, max ver %d\n", min_ver, max_ver);
    121
    122	if (min_ver > APPLE_RTKIT_MAX_SUPPORTED_VERSION) {
    123		dev_err(rtk->dev, "RTKit: Firmware min version %d is too new\n",
    124			min_ver);
    125		goto abort_boot;
    126	}
    127
    128	if (max_ver < APPLE_RTKIT_MIN_SUPPORTED_VERSION) {
    129		dev_err(rtk->dev, "RTKit: Firmware max version %d is too old\n",
    130			max_ver);
    131		goto abort_boot;
    132	}
    133
    134	dev_info(rtk->dev, "RTKit: Initializing (protocol version %d)\n",
    135		 want_ver);
    136	rtk->version = want_ver;
    137
    138	reply = FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MINVER, want_ver);
    139	reply |= FIELD_PREP(APPLE_RTKIT_MGMT_HELLO_MAXVER, want_ver);
    140	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_HELLO_REPLY, reply);
    141
    142	return;
    143
    144abort_boot:
    145	rtk->boot_result = -EINVAL;
    146	complete_all(&rtk->epmap_completion);
    147}
    148
    149static void apple_rtkit_management_rx_epmap(struct apple_rtkit *rtk, u64 msg)
    150{
    151	int i, ep;
    152	u64 reply;
    153	unsigned long bitmap = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BITMAP, msg);
    154	u32 base = FIELD_GET(APPLE_RTKIT_MGMT_EPMAP_BASE, msg);
    155
    156	dev_dbg(rtk->dev,
    157		"RTKit: received endpoint bitmap 0x%lx with base 0x%x\n",
    158		bitmap, base);
    159
    160	for_each_set_bit(i, &bitmap, 32) {
    161		ep = 32 * base + i;
    162		dev_dbg(rtk->dev, "RTKit: Discovered endpoint 0x%02x\n", ep);
    163		set_bit(ep, rtk->endpoints);
    164	}
    165
    166	reply = FIELD_PREP(APPLE_RTKIT_MGMT_EPMAP_BASE, base);
    167	if (msg & APPLE_RTKIT_MGMT_EPMAP_LAST)
    168		reply |= APPLE_RTKIT_MGMT_EPMAP_LAST;
    169	else
    170		reply |= APPLE_RTKIT_MGMT_EPMAP_REPLY_MORE;
    171
    172	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_EPMAP_REPLY, reply);
    173
    174	if (!(msg & APPLE_RTKIT_MGMT_EPMAP_LAST))
    175		return;
    176
    177	for_each_set_bit(ep, rtk->endpoints, APPLE_RTKIT_APP_ENDPOINT_START) {
    178		switch (ep) {
    179		/* the management endpoint is started by default */
    180		case APPLE_RTKIT_EP_MGMT:
    181			break;
    182
    183		/* without starting these RTKit refuses to boot */
    184		case APPLE_RTKIT_EP_SYSLOG:
    185		case APPLE_RTKIT_EP_CRASHLOG:
    186		case APPLE_RTKIT_EP_DEBUG:
    187		case APPLE_RTKIT_EP_IOREPORT:
    188		case APPLE_RTKIT_EP_OSLOG:
    189			dev_dbg(rtk->dev,
    190				"RTKit: Starting system endpoint 0x%02x\n", ep);
    191			apple_rtkit_start_ep(rtk, ep);
    192			break;
    193
    194		default:
    195			dev_warn(rtk->dev,
    196				 "RTKit: Unknown system endpoint: 0x%02x\n",
    197				 ep);
    198		}
    199	}
    200
    201	rtk->boot_result = 0;
    202	complete_all(&rtk->epmap_completion);
    203}
    204
    205static void apple_rtkit_management_rx_iop_pwr_ack(struct apple_rtkit *rtk,
    206						  u64 msg)
    207{
    208	unsigned int new_state = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg);
    209
    210	dev_dbg(rtk->dev, "RTKit: IOP power state transition: 0x%x -> 0x%x\n",
    211		rtk->iop_power_state, new_state);
    212	rtk->iop_power_state = new_state;
    213
    214	complete_all(&rtk->iop_pwr_ack_completion);
    215}
    216
    217static void apple_rtkit_management_rx_ap_pwr_ack(struct apple_rtkit *rtk,
    218						 u64 msg)
    219{
    220	unsigned int new_state = FIELD_GET(APPLE_RTKIT_MGMT_PWR_STATE, msg);
    221
    222	dev_dbg(rtk->dev, "RTKit: AP power state transition: 0x%x -> 0x%x\n",
    223		rtk->ap_power_state, new_state);
    224	rtk->ap_power_state = new_state;
    225
    226	complete_all(&rtk->ap_pwr_ack_completion);
    227}
    228
    229static void apple_rtkit_management_rx(struct apple_rtkit *rtk, u64 msg)
    230{
    231	u8 type = FIELD_GET(APPLE_RTKIT_MGMT_TYPE, msg);
    232
    233	switch (type) {
    234	case APPLE_RTKIT_MGMT_HELLO:
    235		apple_rtkit_management_rx_hello(rtk, msg);
    236		break;
    237	case APPLE_RTKIT_MGMT_EPMAP:
    238		apple_rtkit_management_rx_epmap(rtk, msg);
    239		break;
    240	case APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE_ACK:
    241		apple_rtkit_management_rx_iop_pwr_ack(rtk, msg);
    242		break;
    243	case APPLE_RTKIT_MGMT_SET_AP_PWR_STATE_ACK:
    244		apple_rtkit_management_rx_ap_pwr_ack(rtk, msg);
    245		break;
    246	default:
    247		dev_warn(
    248			rtk->dev,
    249			"RTKit: unknown management message: 0x%llx (type: 0x%02x)\n",
    250			msg, type);
    251	}
    252}
    253
    254static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk,
    255					    struct apple_rtkit_shmem *buffer,
    256					    u8 ep, u64 msg)
    257{
    258	size_t n_4kpages = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg);
    259	u64 reply;
    260	int err;
    261
    262	buffer->buffer = NULL;
    263	buffer->iomem = NULL;
    264	buffer->is_mapped = false;
    265	buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg);
    266	buffer->size = n_4kpages << 12;
    267
    268	dev_dbg(rtk->dev, "RTKit: buffer request for 0x%zx bytes at %pad\n",
    269		buffer->size, &buffer->iova);
    270
    271	if (buffer->iova &&
    272	    (!rtk->ops->shmem_setup || !rtk->ops->shmem_destroy)) {
    273		err = -EINVAL;
    274		goto error;
    275	}
    276
    277	if (rtk->ops->shmem_setup) {
    278		err = rtk->ops->shmem_setup(rtk->cookie, buffer);
    279		if (err)
    280			goto error;
    281	} else {
    282		buffer->buffer = dma_alloc_coherent(rtk->dev, buffer->size,
    283						    &buffer->iova, GFP_KERNEL);
    284		if (!buffer->buffer) {
    285			err = -ENOMEM;
    286			goto error;
    287		}
    288	}
    289
    290	if (!buffer->is_mapped) {
    291		reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE,
    292				   APPLE_RTKIT_BUFFER_REQUEST);
    293		reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, n_4kpages);
    294		reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA,
    295				    buffer->iova);
    296		apple_rtkit_send_message(rtk, ep, reply, NULL, false);
    297	}
    298
    299	return 0;
    300
    301error:
    302	buffer->buffer = NULL;
    303	buffer->iomem = NULL;
    304	buffer->iova = 0;
    305	buffer->size = 0;
    306	buffer->is_mapped = false;
    307	return err;
    308}
    309
    310static void apple_rtkit_free_buffer(struct apple_rtkit *rtk,
    311				    struct apple_rtkit_shmem *bfr)
    312{
    313	if (bfr->size == 0)
    314		return;
    315
    316	if (rtk->ops->shmem_destroy)
    317		rtk->ops->shmem_destroy(rtk->cookie, bfr);
    318	else if (bfr->buffer)
    319		dma_free_coherent(rtk->dev, bfr->size, bfr->buffer, bfr->iova);
    320
    321	bfr->buffer = NULL;
    322	bfr->iomem = NULL;
    323	bfr->iova = 0;
    324	bfr->size = 0;
    325	bfr->is_mapped = false;
    326}
    327
    328static void apple_rtkit_memcpy(struct apple_rtkit *rtk, void *dst,
    329			       struct apple_rtkit_shmem *bfr, size_t offset,
    330			       size_t len)
    331{
    332	if (bfr->iomem)
    333		memcpy_fromio(dst, bfr->iomem + offset, len);
    334	else
    335		memcpy(dst, bfr->buffer + offset, len);
    336}
    337
    338static void apple_rtkit_crashlog_rx(struct apple_rtkit *rtk, u64 msg)
    339{
    340	u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
    341	u8 *bfr;
    342
    343	if (type != APPLE_RTKIT_CRASHLOG_CRASH) {
    344		dev_warn(rtk->dev, "RTKit: Unknown crashlog message: %llx\n",
    345			 msg);
    346		return;
    347	}
    348
    349	if (!rtk->crashlog_buffer.size) {
    350		apple_rtkit_common_rx_get_buffer(rtk, &rtk->crashlog_buffer,
    351						 APPLE_RTKIT_EP_CRASHLOG, msg);
    352		return;
    353	}
    354
    355	dev_err(rtk->dev, "RTKit: co-processor has crashed\n");
    356
    357	/*
    358	 * create a shadow copy here to make sure the co-processor isn't able
    359	 * to change the log while we're dumping it. this also ensures
    360	 * the buffer is in normal memory and not iomem for e.g. the SMC
    361	 */
    362	bfr = kzalloc(rtk->crashlog_buffer.size, GFP_KERNEL);
    363	if (bfr) {
    364		apple_rtkit_memcpy(rtk, bfr, &rtk->crashlog_buffer, 0,
    365				   rtk->crashlog_buffer.size);
    366		apple_rtkit_crashlog_dump(rtk, bfr, rtk->crashlog_buffer.size);
    367		kfree(bfr);
    368	} else {
    369		dev_err(rtk->dev,
    370			"RTKit: Couldn't allocate crashlog shadow buffer\n");
    371	}
    372
    373	rtk->crashed = true;
    374	if (rtk->ops->crashed)
    375		rtk->ops->crashed(rtk->cookie);
    376}
    377
    378static void apple_rtkit_ioreport_rx(struct apple_rtkit *rtk, u64 msg)
    379{
    380	u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
    381
    382	switch (type) {
    383	case APPLE_RTKIT_BUFFER_REQUEST:
    384		apple_rtkit_common_rx_get_buffer(rtk, &rtk->ioreport_buffer,
    385						 APPLE_RTKIT_EP_IOREPORT, msg);
    386		break;
    387	/* unknown, must be ACKed or the co-processor will hang */
    388	case 0x8:
    389	case 0xc:
    390		apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_IOREPORT, msg,
    391					 NULL, false);
    392		break;
    393	default:
    394		dev_warn(rtk->dev, "RTKit: Unknown ioreport message: %llx\n",
    395			 msg);
    396	}
    397}
    398
    399static void apple_rtkit_syslog_rx_init(struct apple_rtkit *rtk, u64 msg)
    400{
    401	rtk->syslog_n_entries = FIELD_GET(APPLE_RTKIT_SYSLOG_N_ENTRIES, msg);
    402	rtk->syslog_msg_size = FIELD_GET(APPLE_RTKIT_SYSLOG_MSG_SIZE, msg);
    403
    404	rtk->syslog_msg_buffer = kzalloc(rtk->syslog_msg_size, GFP_KERNEL);
    405
    406	dev_dbg(rtk->dev,
    407		"RTKit: syslog initialized: entries: %zd, msg_size: %zd\n",
    408		rtk->syslog_n_entries, rtk->syslog_msg_size);
    409}
    410
    411static void apple_rtkit_syslog_rx_log(struct apple_rtkit *rtk, u64 msg)
    412{
    413	u8 idx = msg & 0xff;
    414	char log_context[24];
    415	size_t entry_size = 0x20 + rtk->syslog_msg_size;
    416
    417	if (!rtk->syslog_msg_buffer) {
    418		dev_warn(
    419			rtk->dev,
    420			"RTKit: received syslog message but no syslog_msg_buffer\n");
    421		goto done;
    422	}
    423	if (!rtk->syslog_buffer.size) {
    424		dev_warn(
    425			rtk->dev,
    426			"RTKit: received syslog message but syslog_buffer.size is zero\n");
    427		goto done;
    428	}
    429	if (!rtk->syslog_buffer.buffer && !rtk->syslog_buffer.iomem) {
    430		dev_warn(
    431			rtk->dev,
    432			"RTKit: received syslog message but no syslog_buffer.buffer or syslog_buffer.iomem\n");
    433		goto done;
    434	}
    435	if (idx > rtk->syslog_n_entries) {
    436		dev_warn(rtk->dev, "RTKit: syslog index %d out of range\n",
    437			 idx);
    438		goto done;
    439	}
    440
    441	apple_rtkit_memcpy(rtk, log_context, &rtk->syslog_buffer,
    442			   idx * entry_size + 8, sizeof(log_context));
    443	apple_rtkit_memcpy(rtk, rtk->syslog_msg_buffer, &rtk->syslog_buffer,
    444			   idx * entry_size + 8 + sizeof(log_context),
    445			   rtk->syslog_msg_size);
    446
    447	log_context[sizeof(log_context) - 1] = 0;
    448	rtk->syslog_msg_buffer[rtk->syslog_msg_size - 1] = 0;
    449	dev_info(rtk->dev, "RTKit: syslog message: %s: %s\n", log_context,
    450		 rtk->syslog_msg_buffer);
    451
    452done:
    453	apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_SYSLOG, msg, NULL, false);
    454}
    455
    456static void apple_rtkit_syslog_rx(struct apple_rtkit *rtk, u64 msg)
    457{
    458	u8 type = FIELD_GET(APPLE_RTKIT_SYSLOG_TYPE, msg);
    459
    460	switch (type) {
    461	case APPLE_RTKIT_BUFFER_REQUEST:
    462		apple_rtkit_common_rx_get_buffer(rtk, &rtk->syslog_buffer,
    463						 APPLE_RTKIT_EP_SYSLOG, msg);
    464		break;
    465	case APPLE_RTKIT_SYSLOG_INIT:
    466		apple_rtkit_syslog_rx_init(rtk, msg);
    467		break;
    468	case APPLE_RTKIT_SYSLOG_LOG:
    469		apple_rtkit_syslog_rx_log(rtk, msg);
    470		break;
    471	default:
    472		dev_warn(rtk->dev, "RTKit: Unknown syslog message: %llx\n",
    473			 msg);
    474	}
    475}
    476
    477static void apple_rtkit_oslog_rx_init(struct apple_rtkit *rtk, u64 msg)
    478{
    479	u64 ack;
    480
    481	dev_dbg(rtk->dev, "RTKit: oslog init: msg: 0x%llx\n", msg);
    482	ack = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE, APPLE_RTKIT_OSLOG_ACK);
    483	apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_OSLOG, ack, NULL, false);
    484}
    485
    486static void apple_rtkit_oslog_rx(struct apple_rtkit *rtk, u64 msg)
    487{
    488	u8 type = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg);
    489
    490	switch (type) {
    491	case APPLE_RTKIT_OSLOG_INIT:
    492		apple_rtkit_oslog_rx_init(rtk, msg);
    493		break;
    494	default:
    495		dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n", msg);
    496	}
    497}
    498
    499static void apple_rtkit_rx_work(struct work_struct *work)
    500{
    501	struct apple_rtkit_rx_work *rtk_work =
    502		container_of(work, struct apple_rtkit_rx_work, work);
    503	struct apple_rtkit *rtk = rtk_work->rtk;
    504
    505	switch (rtk_work->ep) {
    506	case APPLE_RTKIT_EP_MGMT:
    507		apple_rtkit_management_rx(rtk, rtk_work->msg);
    508		break;
    509	case APPLE_RTKIT_EP_CRASHLOG:
    510		apple_rtkit_crashlog_rx(rtk, rtk_work->msg);
    511		break;
    512	case APPLE_RTKIT_EP_SYSLOG:
    513		apple_rtkit_syslog_rx(rtk, rtk_work->msg);
    514		break;
    515	case APPLE_RTKIT_EP_IOREPORT:
    516		apple_rtkit_ioreport_rx(rtk, rtk_work->msg);
    517		break;
    518	case APPLE_RTKIT_EP_OSLOG:
    519		apple_rtkit_oslog_rx(rtk, rtk_work->msg);
    520		break;
    521	case APPLE_RTKIT_APP_ENDPOINT_START ... 0xff:
    522		if (rtk->ops->recv_message)
    523			rtk->ops->recv_message(rtk->cookie, rtk_work->ep,
    524					       rtk_work->msg);
    525		else
    526			dev_warn(
    527				rtk->dev,
    528				"Received unexpected message to EP%02d: %llx\n",
    529				rtk_work->ep, rtk_work->msg);
    530		break;
    531	default:
    532		dev_warn(rtk->dev,
    533			 "RTKit: message to unknown endpoint %02x: %llx\n",
    534			 rtk_work->ep, rtk_work->msg);
    535	}
    536
    537	kfree(rtk_work);
    538}
    539
    540static void apple_rtkit_rx(struct mbox_client *cl, void *mssg)
    541{
    542	struct apple_rtkit *rtk = container_of(cl, struct apple_rtkit, mbox_cl);
    543	struct apple_mbox_msg *msg = mssg;
    544	struct apple_rtkit_rx_work *work;
    545	u8 ep = msg->msg1;
    546
    547	/*
    548	 * The message was read from a MMIO FIFO and we have to make
    549	 * sure all reads from buffers sent with that message happen
    550	 * afterwards.
    551	 */
    552	dma_rmb();
    553
    554	if (!test_bit(ep, rtk->endpoints))
    555		dev_warn(rtk->dev,
    556			 "RTKit: Message to undiscovered endpoint 0x%02x\n",
    557			 ep);
    558
    559	if (ep >= APPLE_RTKIT_APP_ENDPOINT_START &&
    560	    rtk->ops->recv_message_early &&
    561	    rtk->ops->recv_message_early(rtk->cookie, ep, msg->msg0))
    562		return;
    563
    564	work = kzalloc(sizeof(*work), GFP_ATOMIC);
    565	if (!work)
    566		return;
    567
    568	work->rtk = rtk;
    569	work->ep = ep;
    570	work->msg = msg->msg0;
    571	INIT_WORK(&work->work, apple_rtkit_rx_work);
    572	queue_work(rtk->wq, &work->work);
    573}
    574
    575static void apple_rtkit_tx_done(struct mbox_client *cl, void *mssg, int r)
    576{
    577	struct apple_rtkit_msg *msg =
    578		container_of(mssg, struct apple_rtkit_msg, mbox_msg);
    579
    580	if (r == -ETIME)
    581		return;
    582
    583	if (msg->completion)
    584		complete(msg->completion);
    585	kfree(msg);
    586}
    587
    588int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message,
    589			     struct completion *completion, bool atomic)
    590{
    591	struct apple_rtkit_msg *msg;
    592	int ret;
    593	gfp_t flags;
    594
    595	if (rtk->crashed)
    596		return -EINVAL;
    597	if (ep >= APPLE_RTKIT_APP_ENDPOINT_START &&
    598	    !apple_rtkit_is_running(rtk))
    599		return -EINVAL;
    600
    601	if (atomic)
    602		flags = GFP_ATOMIC;
    603	else
    604		flags = GFP_KERNEL;
    605
    606	msg = kzalloc(sizeof(*msg), flags);
    607	if (!msg)
    608		return -ENOMEM;
    609
    610	msg->mbox_msg.msg0 = message;
    611	msg->mbox_msg.msg1 = ep;
    612	msg->completion = completion;
    613
    614	/*
    615	 * The message will be sent with a MMIO write. We need the barrier
    616	 * here to ensure any previous writes to buffers are visible to the
    617	 * device before that MMIO write happens.
    618	 */
    619	dma_wmb();
    620
    621	ret = mbox_send_message(rtk->mbox_chan, &msg->mbox_msg);
    622	if (ret < 0) {
    623		kfree(msg);
    624		return ret;
    625	}
    626
    627	return 0;
    628}
    629EXPORT_SYMBOL_GPL(apple_rtkit_send_message);
    630
    631int apple_rtkit_send_message_wait(struct apple_rtkit *rtk, u8 ep, u64 message,
    632				  unsigned long timeout, bool atomic)
    633{
    634	DECLARE_COMPLETION_ONSTACK(completion);
    635	int ret;
    636	long t;
    637
    638	ret = apple_rtkit_send_message(rtk, ep, message, &completion, atomic);
    639	if (ret < 0)
    640		return ret;
    641
    642	if (atomic) {
    643		ret = mbox_flush(rtk->mbox_chan, timeout);
    644		if (ret < 0)
    645			return ret;
    646
    647		if (try_wait_for_completion(&completion))
    648			return 0;
    649
    650		return -ETIME;
    651	} else {
    652		t = wait_for_completion_interruptible_timeout(
    653			&completion, msecs_to_jiffies(timeout));
    654		if (t < 0)
    655			return t;
    656		else if (t == 0)
    657			return -ETIME;
    658		return 0;
    659	}
    660}
    661EXPORT_SYMBOL_GPL(apple_rtkit_send_message_wait);
    662
    663int apple_rtkit_start_ep(struct apple_rtkit *rtk, u8 endpoint)
    664{
    665	u64 msg;
    666
    667	if (!test_bit(endpoint, rtk->endpoints))
    668		return -EINVAL;
    669	if (endpoint >= APPLE_RTKIT_APP_ENDPOINT_START &&
    670	    !apple_rtkit_is_running(rtk))
    671		return -EINVAL;
    672
    673	msg = FIELD_PREP(APPLE_RTKIT_MGMT_STARTEP_EP, endpoint);
    674	msg |= APPLE_RTKIT_MGMT_STARTEP_FLAG;
    675	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_STARTEP, msg);
    676
    677	return 0;
    678}
    679EXPORT_SYMBOL_GPL(apple_rtkit_start_ep);
    680
    681static int apple_rtkit_request_mbox_chan(struct apple_rtkit *rtk)
    682{
    683	if (rtk->mbox_name)
    684		rtk->mbox_chan = mbox_request_channel_byname(&rtk->mbox_cl,
    685							     rtk->mbox_name);
    686	else
    687		rtk->mbox_chan =
    688			mbox_request_channel(&rtk->mbox_cl, rtk->mbox_idx);
    689
    690	if (IS_ERR(rtk->mbox_chan))
    691		return PTR_ERR(rtk->mbox_chan);
    692	return 0;
    693}
    694
    695static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
    696					    const char *mbox_name, int mbox_idx,
    697					    const struct apple_rtkit_ops *ops)
    698{
    699	struct apple_rtkit *rtk;
    700	int ret;
    701
    702	if (!ops)
    703		return ERR_PTR(-EINVAL);
    704
    705	rtk = kzalloc(sizeof(*rtk), GFP_KERNEL);
    706	if (!rtk)
    707		return ERR_PTR(-ENOMEM);
    708
    709	rtk->dev = dev;
    710	rtk->cookie = cookie;
    711	rtk->ops = ops;
    712
    713	init_completion(&rtk->epmap_completion);
    714	init_completion(&rtk->iop_pwr_ack_completion);
    715	init_completion(&rtk->ap_pwr_ack_completion);
    716
    717	bitmap_zero(rtk->endpoints, APPLE_RTKIT_MAX_ENDPOINTS);
    718	set_bit(APPLE_RTKIT_EP_MGMT, rtk->endpoints);
    719
    720	rtk->mbox_name = mbox_name;
    721	rtk->mbox_idx = mbox_idx;
    722	rtk->mbox_cl.dev = dev;
    723	rtk->mbox_cl.tx_block = false;
    724	rtk->mbox_cl.knows_txdone = false;
    725	rtk->mbox_cl.rx_callback = &apple_rtkit_rx;
    726	rtk->mbox_cl.tx_done = &apple_rtkit_tx_done;
    727
    728	rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_MEM_RECLAIM,
    729					  dev_name(rtk->dev));
    730	if (!rtk->wq) {
    731		ret = -ENOMEM;
    732		goto free_rtk;
    733	}
    734
    735	ret = apple_rtkit_request_mbox_chan(rtk);
    736	if (ret)
    737		goto destroy_wq;
    738
    739	return rtk;
    740
    741destroy_wq:
    742	destroy_workqueue(rtk->wq);
    743free_rtk:
    744	kfree(rtk);
    745	return ERR_PTR(ret);
    746}
    747
    748static int apple_rtkit_wait_for_completion(struct completion *c)
    749{
    750	long t;
    751
    752	t = wait_for_completion_interruptible_timeout(c,
    753						      msecs_to_jiffies(1000));
    754	if (t < 0)
    755		return t;
    756	else if (t == 0)
    757		return -ETIME;
    758	else
    759		return 0;
    760}
    761
    762int apple_rtkit_reinit(struct apple_rtkit *rtk)
    763{
    764	/* make sure we don't handle any messages while reinitializing */
    765	mbox_free_channel(rtk->mbox_chan);
    766	flush_workqueue(rtk->wq);
    767
    768	apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
    769	apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
    770	apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
    771
    772	kfree(rtk->syslog_msg_buffer);
    773
    774	rtk->syslog_msg_buffer = NULL;
    775	rtk->syslog_n_entries = 0;
    776	rtk->syslog_msg_size = 0;
    777
    778	bitmap_zero(rtk->endpoints, APPLE_RTKIT_MAX_ENDPOINTS);
    779	set_bit(APPLE_RTKIT_EP_MGMT, rtk->endpoints);
    780
    781	reinit_completion(&rtk->epmap_completion);
    782	reinit_completion(&rtk->iop_pwr_ack_completion);
    783	reinit_completion(&rtk->ap_pwr_ack_completion);
    784
    785	rtk->crashed = false;
    786	rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_OFF;
    787	rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_OFF;
    788
    789	return apple_rtkit_request_mbox_chan(rtk);
    790}
    791EXPORT_SYMBOL_GPL(apple_rtkit_reinit);
    792
    793static int apple_rtkit_set_ap_power_state(struct apple_rtkit *rtk,
    794					  unsigned int state)
    795{
    796	u64 msg;
    797	int ret;
    798
    799	reinit_completion(&rtk->ap_pwr_ack_completion);
    800
    801	msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
    802	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE,
    803				    msg);
    804
    805	ret = apple_rtkit_wait_for_completion(&rtk->ap_pwr_ack_completion);
    806	if (ret)
    807		return ret;
    808
    809	if (rtk->ap_power_state != state)
    810		return -EINVAL;
    811	return 0;
    812}
    813
    814static int apple_rtkit_set_iop_power_state(struct apple_rtkit *rtk,
    815					   unsigned int state)
    816{
    817	u64 msg;
    818	int ret;
    819
    820	reinit_completion(&rtk->iop_pwr_ack_completion);
    821
    822	msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
    823	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
    824				    msg);
    825
    826	ret = apple_rtkit_wait_for_completion(&rtk->iop_pwr_ack_completion);
    827	if (ret)
    828		return ret;
    829
    830	if (rtk->iop_power_state != state)
    831		return -EINVAL;
    832	return 0;
    833}
    834
    835int apple_rtkit_boot(struct apple_rtkit *rtk)
    836{
    837	int ret;
    838
    839	if (apple_rtkit_is_running(rtk))
    840		return 0;
    841	if (rtk->crashed)
    842		return -EINVAL;
    843
    844	dev_dbg(rtk->dev, "RTKit: waiting for boot to finish\n");
    845	ret = apple_rtkit_wait_for_completion(&rtk->epmap_completion);
    846	if (ret)
    847		return ret;
    848	if (rtk->boot_result)
    849		return rtk->boot_result;
    850
    851	dev_dbg(rtk->dev, "RTKit: waiting for IOP power state ACK\n");
    852	ret = apple_rtkit_wait_for_completion(&rtk->iop_pwr_ack_completion);
    853	if (ret)
    854		return ret;
    855
    856	return apple_rtkit_set_ap_power_state(rtk, APPLE_RTKIT_PWR_STATE_ON);
    857}
    858EXPORT_SYMBOL_GPL(apple_rtkit_boot);
    859
    860int apple_rtkit_shutdown(struct apple_rtkit *rtk)
    861{
    862	int ret;
    863
    864	/* if OFF is used here the co-processor will not wake up again */
    865	ret = apple_rtkit_set_ap_power_state(rtk,
    866					     APPLE_RTKIT_PWR_STATE_QUIESCED);
    867	if (ret)
    868		return ret;
    869
    870	ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_SLEEP);
    871	if (ret)
    872		return ret;
    873
    874	return apple_rtkit_reinit(rtk);
    875}
    876EXPORT_SYMBOL_GPL(apple_rtkit_shutdown);
    877
    878int apple_rtkit_quiesce(struct apple_rtkit *rtk)
    879{
    880	int ret;
    881
    882	ret = apple_rtkit_set_ap_power_state(rtk,
    883					     APPLE_RTKIT_PWR_STATE_QUIESCED);
    884	if (ret)
    885		return ret;
    886
    887	ret = apple_rtkit_set_iop_power_state(rtk,
    888					      APPLE_RTKIT_PWR_STATE_QUIESCED);
    889	if (ret)
    890		return ret;
    891
    892	ret = apple_rtkit_reinit(rtk);
    893	if (ret)
    894		return ret;
    895
    896	rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_QUIESCED;
    897	rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_QUIESCED;
    898	return 0;
    899}
    900EXPORT_SYMBOL_GPL(apple_rtkit_quiesce);
    901
    902int apple_rtkit_wake(struct apple_rtkit *rtk)
    903{
    904	u64 msg;
    905
    906	if (apple_rtkit_is_running(rtk))
    907		return -EINVAL;
    908
    909	reinit_completion(&rtk->iop_pwr_ack_completion);
    910
    911	/*
    912	 * Use open-coded apple_rtkit_set_iop_power_state since apple_rtkit_boot
    913	 * will wait for the completion anyway.
    914	 */
    915	msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_ON);
    916	apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
    917				    msg);
    918
    919	return apple_rtkit_boot(rtk);
    920}
    921EXPORT_SYMBOL_GPL(apple_rtkit_wake);
    922
    923static void apple_rtkit_free(struct apple_rtkit *rtk)
    924{
    925	mbox_free_channel(rtk->mbox_chan);
    926	destroy_workqueue(rtk->wq);
    927
    928	apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
    929	apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
    930	apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
    931
    932	kfree(rtk->syslog_msg_buffer);
    933	kfree(rtk);
    934}
    935
    936struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
    937					  const char *mbox_name, int mbox_idx,
    938					  const struct apple_rtkit_ops *ops)
    939{
    940	struct apple_rtkit *rtk;
    941	int ret;
    942
    943	rtk = apple_rtkit_init(dev, cookie, mbox_name, mbox_idx, ops);
    944	if (IS_ERR(rtk))
    945		return rtk;
    946
    947	ret = devm_add_action_or_reset(dev, (void (*)(void *))apple_rtkit_free,
    948				       rtk);
    949	if (ret)
    950		return ERR_PTR(ret);
    951
    952	return rtk;
    953}
    954EXPORT_SYMBOL_GPL(devm_apple_rtkit_init);
    955
    956MODULE_LICENSE("Dual MIT/GPL");
    957MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
    958MODULE_DESCRIPTION("Apple RTKit driver");