rtkit.c 24 KB

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