brintos

brintos / linux-shallow public Read only

0
0
Text · 6.0 KiB · 8319e36 Raw
248 lines · c
1// SPDX-License-Identifier: GPL-2.0-only OR MIT2/*3 * Apple RTKit IPC library4 * Copyright (C) The Asahi Linux Contributors5 */6#include "rtkit-internal.h"7 8#define FOURCC(a, b, c, d) \9	(((u32)(a) << 24) | ((u32)(b) << 16) | ((u32)(c) << 8) | ((u32)(d)))10 11#define APPLE_RTKIT_CRASHLOG_HEADER FOURCC('C', 'L', 'H', 'E')12#define APPLE_RTKIT_CRASHLOG_STR FOURCC('C', 's', 't', 'r')13#define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r')14#define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x')15#define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm')16#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8')17 18/* For COMPILE_TEST on non-ARM64 architectures */19#ifndef PSR_MODE_EL0t20#define PSR_MODE_EL0t	0x0000000021#define PSR_MODE_EL1t	0x0000000422#define PSR_MODE_EL1h	0x0000000523#define PSR_MODE_EL2t	0x0000000824#define PSR_MODE_EL2h	0x0000000925#define PSR_MODE_MASK	0x0000000f26#endif27 28struct apple_rtkit_crashlog_header {29	u32 fourcc;30	u32 version;31	u32 size;32	u32 flags;33	u8 _unk[16];34};35static_assert(sizeof(struct apple_rtkit_crashlog_header) == 0x20);36 37struct apple_rtkit_crashlog_mbox_entry {38	u64 msg0;39	u64 msg1;40	u32 timestamp;41	u8 _unk[4];42};43static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18);44 45struct apple_rtkit_crashlog_regs {46	u32 unk_0;47	u32 unk_4;48	u64 regs[31];49	u64 sp;50	u64 pc;51	u64 psr;52	u64 cpacr;53	u64 fpsr;54	u64 fpcr;55	u64 unk[64];56	u64 far;57	u64 unk_X;58	u64 esr;59	u64 unk_Z;60} __packed;61static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350);62 63static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,64					  size_t size)65{66	u32 idx;67	u8 *ptr, *end;68 69	memcpy(&idx, bfr, 4);70 71	ptr = bfr + 4;72	end = bfr + size;73	while (ptr < end) {74		u8 *newline = memchr(ptr, '\n', end - ptr);75 76		if (newline) {77			u8 tmp = *newline;78			*newline = '\0';79			dev_warn(rtk->dev, "RTKit: Message (id=%x): %s\n", idx,80				 ptr);81			*newline = tmp;82			ptr = newline + 1;83		} else {84			dev_warn(rtk->dev, "RTKit: Message (id=%x): %s", idx,85				 ptr);86			break;87		}88	}89}90 91static void apple_rtkit_crashlog_dump_version(struct apple_rtkit *rtk, u8 *bfr,92					      size_t size)93{94	dev_warn(rtk->dev, "RTKit: Version: %s", bfr + 16);95}96 97static void apple_rtkit_crashlog_dump_time(struct apple_rtkit *rtk, u8 *bfr,98					   size_t size)99{100	u64 crash_time;101 102	memcpy(&crash_time, bfr, 8);103	dev_warn(rtk->dev, "RTKit: Crash time: %lld", crash_time);104}105 106static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr,107					      size_t size)108{109	u32 type, index, i;110	size_t n_messages;111	struct apple_rtkit_crashlog_mbox_entry entry;112 113	memcpy(&type, bfr + 16, 4);114	memcpy(&index, bfr + 24, 4);115	n_messages = (size - 28) / sizeof(entry);116 117	dev_warn(rtk->dev, "RTKit: Mailbox history (type = %d, index = %d)",118		 type, index);119	for (i = 0; i < n_messages; ++i) {120		memcpy(&entry, bfr + 28 + i * sizeof(entry), sizeof(entry));121		dev_warn(rtk->dev, "RTKit:  #%03d@%08x: %016llx %016llx", i,122			 entry.timestamp, entry.msg0, entry.msg1);123	}124}125 126static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,127					   size_t size)128{129	struct apple_rtkit_crashlog_regs *regs;130	const char *el;131	int i;132 133	if (size < sizeof(*regs)) {134		dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size);135		return;136	}137 138	regs = (struct apple_rtkit_crashlog_regs *)bfr;139 140	switch (regs->psr & PSR_MODE_MASK) {141	case PSR_MODE_EL0t:142		el = "EL0t";143		break;144	case PSR_MODE_EL1t:145		el = "EL1t";146		break;147	case PSR_MODE_EL1h:148		el = "EL1h";149		break;150	case PSR_MODE_EL2t:151		el = "EL2t";152		break;153	case PSR_MODE_EL2h:154		el = "EL2h";155		break;156	default:157		el = "unknown";158		break;159	}160 161	dev_warn(rtk->dev, "RTKit: Exception dump:");162	dev_warn(rtk->dev, "  == Exception taken from %s ==", el);163	dev_warn(rtk->dev, "  PSR    = 0x%llx", regs->psr);164	dev_warn(rtk->dev, "  PC     = 0x%llx\n", regs->pc);165	dev_warn(rtk->dev, "  ESR    = 0x%llx\n", regs->esr);166	dev_warn(rtk->dev, "  FAR    = 0x%llx\n", regs->far);167	dev_warn(rtk->dev, "  SP     = 0x%llx\n", regs->sp);168	dev_warn(rtk->dev, "\n");169 170	for (i = 0; i < 31; i += 4) {171		if (i < 28)172			dev_warn(rtk->dev,173					 "  x%02d-x%02d = %016llx %016llx %016llx %016llx\n",174					 i, i + 3,175					 regs->regs[i], regs->regs[i + 1],176					 regs->regs[i + 2], regs->regs[i + 3]);177		else178			dev_warn(rtk->dev,179					 "  x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3,180					 regs->regs[i], regs->regs[i + 1], regs->regs[i + 2]);181	}182 183	dev_warn(rtk->dev, "\n");184}185 186void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)187{188	size_t offset;189	u32 section_fourcc, section_size;190	struct apple_rtkit_crashlog_header header;191 192	memcpy(&header, bfr, sizeof(header));193	if (header.fourcc != APPLE_RTKIT_CRASHLOG_HEADER) {194		dev_warn(rtk->dev, "RTKit: Expected crashlog header but got %x",195			 header.fourcc);196		return;197	}198 199	if (header.size > size) {200		dev_warn(rtk->dev, "RTKit: Crashlog size (%x) is too large",201			 header.size);202		return;203	}204 205	size = header.size;206	offset = sizeof(header);207 208	while (offset < size) {209		memcpy(&section_fourcc, bfr + offset, 4);210		memcpy(&section_size, bfr + offset + 12, 4);211 212		switch (section_fourcc) {213		case APPLE_RTKIT_CRASHLOG_HEADER:214			dev_dbg(rtk->dev, "RTKit: End of crashlog reached");215			return;216		case APPLE_RTKIT_CRASHLOG_STR:217			apple_rtkit_crashlog_dump_str(rtk, bfr + offset + 16,218						      section_size);219			break;220		case APPLE_RTKIT_CRASHLOG_VERSION:221			apple_rtkit_crashlog_dump_version(222				rtk, bfr + offset + 16, section_size);223			break;224		case APPLE_RTKIT_CRASHLOG_MBOX:225			apple_rtkit_crashlog_dump_mailbox(226				rtk, bfr + offset + 16, section_size);227			break;228		case APPLE_RTKIT_CRASHLOG_TIME:229			apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16,230						       section_size);231			break;232		case APPLE_RTKIT_CRASHLOG_REGS:233			apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16,234						       section_size);235			break;236		default:237			dev_warn(rtk->dev,238				 "RTKit: Unknown crashlog section: %x",239				 section_fourcc);240		}241 242		offset += section_size;243	}244 245	dev_warn(rtk->dev,246		 "RTKit: End of crashlog reached but no footer present");247}248