diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index d2acfac73003..76a6a0e6ae4f 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -37,6 +37,7 @@ config ARCH_APPLE bool "Apple Silicon SoC family" select APPLE_AIC select APPLE_PMGR_PWRSTATE if PM + select HAVE_SHARED_GPIOS help This enables support for Apple's in-house ARM SoC family, such as the Apple M1. diff --git a/drivers/soc/apple/rtkit-crashlog.c b/drivers/soc/apple/rtkit-crashlog.c index 8319e365110b..195b7869ce58 100644 --- a/drivers/soc/apple/rtkit-crashlog.c +++ b/drivers/soc/apple/rtkit-crashlog.c @@ -13,7 +13,8 @@ #define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r') #define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x') #define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm') -#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8') +#define APPLE_RTKIT_CRASHLOG_AARCH32 FOURCC('C', 'r', 'g', 'A') +#define APPLE_RTKIT_CRASHLOG_AARCH64 FOURCC('C', 'r', 'g', '8') /* For COMPILE_TEST on non-ARM64 architectures */ #ifndef PSR_MODE_EL0t @@ -25,6 +26,21 @@ #define PSR_MODE_MASK 0x0000000f #endif +/* + * AArch32 mode definitions: APPLE_RTKIT depends on APPLE_MAILBOX, which + * depends on 64BIT, so there is no need to care about COMPILE_TEST on ARM. + */ +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define MON_MODE 0x00000016 +#define ABT_MODE 0x00000017 +#define HYP_MODE 0x0000001a +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE_MASK_32 0x0000001f + struct apple_rtkit_crashlog_header { u32 fourcc; u32 version; @@ -42,7 +58,7 @@ struct apple_rtkit_crashlog_mbox_entry { }; static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18); -struct apple_rtkit_crashlog_regs { +struct apple_rtkit_crashlog_aarch64 { u32 unk_0; u32 unk_4; u64 regs[31]; @@ -58,7 +74,21 @@ struct apple_rtkit_crashlog_regs { u64 esr; u64 unk_Z; } __packed; -static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350); +static_assert(sizeof(struct apple_rtkit_crashlog_aarch64) == 0x350); + +struct apple_rtkit_crashlog_aarch32 { + u32 unk_0; + u32 unk_4; + u32 regs[16]; + u32 psr; + u32 unk_x1; + u8 stack[0x100]; + u32 unk_x2; + u32 unk_x3; + u32 unk_x4; + u32 unk_x5; +} __packed; +static_assert(sizeof(struct apple_rtkit_crashlog_aarch32) == 0x160); static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr, size_t size) @@ -123,21 +153,84 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr, } } -static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, - size_t size) +static void apple_rtkit_crashlog_dump_aarch32(struct apple_rtkit *rtk, u8 *bfr, + size_t size) { - struct apple_rtkit_crashlog_regs *regs; - const char *el; + struct apple_rtkit_crashlog_aarch32 *state; + const char *mode; int i; - if (size < sizeof(*regs)) { - dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size); + if (size < sizeof(*state)) { + dev_warn(rtk->dev, "RTKit: AArch32 section too small: 0x%zx", size); return; } - regs = (struct apple_rtkit_crashlog_regs *)bfr; + state = (struct apple_rtkit_crashlog_aarch32 *)bfr; - switch (regs->psr & PSR_MODE_MASK) { + switch (state->psr & MODE_MASK_32) { + case USR_MODE: + mode = "User"; + break; + case FIQ_MODE: + mode = "FIQ"; + break; + case IRQ_MODE: + mode = "IRQ"; + break; + case SVC_MODE: + mode = "Supervisor"; + break; + case MON_MODE: + mode = "Monitor"; + break; + case ABT_MODE: + mode = "Abort"; + break; + case HYP_MODE: + mode = "Hypervisor"; + break; + case UND_MODE: + mode = "Undefined"; + break; + case SYSTEM_MODE: + mode = "System"; + break; + default: + mode = "Unknown"; + break; + } + + dev_warn(rtk->dev, "RTKit: Exception dump:"); + dev_warn(rtk->dev, " == Exception taken from %s mode ==", mode); + dev_warn(rtk->dev, " PSR = 0x%x", state->psr); + dev_warn(rtk->dev, "\n"); + + for (i = 0; i < 16; i += 4) + dev_warn(rtk->dev, + " r%02d-r%02d = %08x %08x %08x %08x\n", + i, i + 3, + state->regs[i], state->regs[i + 1], + state->regs[i + 2], state->regs[i + 3]); + + dev_warn(rtk->dev, "\n"); +} + +static void apple_rtkit_crashlog_dump_aarch64(struct apple_rtkit *rtk, u8 *bfr, + size_t size) +{ + struct apple_rtkit_crashlog_aarch64 *state; + const char *el; + int i; + + if (size < sizeof(*state)) { + dev_warn(rtk->dev, "RTKit: AArch64 section too small: 0x%zx", + size); + return; + } + + state = (struct apple_rtkit_crashlog_aarch64 *)bfr; + + switch (state->psr & PSR_MODE_MASK) { case PSR_MODE_EL0t: el = "EL0t"; break; @@ -160,11 +253,11 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, dev_warn(rtk->dev, "RTKit: Exception dump:"); dev_warn(rtk->dev, " == Exception taken from %s ==", el); - dev_warn(rtk->dev, " PSR = 0x%llx", regs->psr); - dev_warn(rtk->dev, " PC = 0x%llx\n", regs->pc); - dev_warn(rtk->dev, " ESR = 0x%llx\n", regs->esr); - dev_warn(rtk->dev, " FAR = 0x%llx\n", regs->far); - dev_warn(rtk->dev, " SP = 0x%llx\n", regs->sp); + dev_warn(rtk->dev, " PSR = 0x%llx", state->psr); + dev_warn(rtk->dev, " PC = 0x%llx\n", state->pc); + dev_warn(rtk->dev, " ESR = 0x%llx\n", state->esr); + dev_warn(rtk->dev, " FAR = 0x%llx\n", state->far); + dev_warn(rtk->dev, " SP = 0x%llx\n", state->sp); dev_warn(rtk->dev, "\n"); for (i = 0; i < 31; i += 4) { @@ -172,12 +265,12 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, dev_warn(rtk->dev, " x%02d-x%02d = %016llx %016llx %016llx %016llx\n", i, i + 3, - regs->regs[i], regs->regs[i + 1], - regs->regs[i + 2], regs->regs[i + 3]); + state->regs[i], state->regs[i + 1], + state->regs[i + 2], state->regs[i + 3]); else dev_warn(rtk->dev, " x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3, - regs->regs[i], regs->regs[i + 1], regs->regs[i + 2]); + state->regs[i], state->regs[i + 1], state->regs[i + 2]); } dev_warn(rtk->dev, "\n"); @@ -229,9 +322,13 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size) apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16, section_size); break; - case APPLE_RTKIT_CRASHLOG_REGS: - apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16, - section_size); + case APPLE_RTKIT_CRASHLOG_AARCH32: + apple_rtkit_crashlog_dump_aarch32(rtk, bfr + offset + 16, + section_size); + break; + case APPLE_RTKIT_CRASHLOG_AARCH64: + apple_rtkit_crashlog_dump_aarch64(rtk, bfr + offset + 16, + section_size); break; default: dev_warn(rtk->dev,