1/* @title: Kernel Panic Interface */
2#pragma once
3#include <console/crash.h>
4
5__noreturn void panic_impl_default(struct crash_payload payload,
6 const char *file, int line, const char *func,
7 const char *fmt, ...);
8
9#define _panic_pick(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, NAME, ...) \
10 NAME
11
12#define _panic_dispatch(default, name, ...) \
13 _panic_pick(__VA_ARGS__, name##_n, name##_n, name##_n, name##_n, name##_n, \
14 name##_n, name##_n, name##_n, name##_n, name##_2, \
15 name##_1)(default, __VA_ARGS__)
16
17#define _panic_as_code(x) __comptime_as_type(enum crash_code, x)
18
19/*
20 * panic(CODE)
21 * panic("msg")
22 */
23#define _panic_1(default, x) \
24 __builtin_choose_expr( \
25 __comptime_is_str(x), \
26 panic_impl_default(CRASH_CODE_TO_PAYLOAD(default), __FILE__, __LINE__, \
27 __func__, __comptime_as_str(x)), \
28 panic_impl_default(CRASH_CODE_TO_PAYLOAD(_panic_as_code(x)), __FILE__, \
29 __LINE__, __func__, "No message supplied"))
30/*
31 * panic(CODE, "msg")
32 * panic("msg %d", 12)
33 */
34#define _panic_2(default, x, y) \
35 __builtin_choose_expr( \
36 __comptime_is_str(x), \
37 panic_impl_default(CRASH_CODE_TO_PAYLOAD(default), __FILE__, __LINE__, \
38 __func__, __comptime_as_str(x), \
39 y), /* x is format, y is first vararg */ \
40 panic_impl_default(CRASH_CODE_TO_PAYLOAD(_panic_as_code(x)), __FILE__, \
41 __LINE__, __func__, __comptime_as_str(y)))
42
43/*
44 * panic(CODE, "msg %d", 12)
45 * panic("msg %d %d", 12, 13)
46 */
47#define _panic_n(default, x, y, ...) \
48 __builtin_choose_expr( \
49 __comptime_is_str(x), \
50 panic_impl_default(CRASH_CODE_TO_PAYLOAD(default), __FILE__, __LINE__, \
51 __func__, __comptime_as_str(x), y, ##__VA_ARGS__), \
52 panic_impl_default(CRASH_CODE_TO_PAYLOAD(_panic_as_code(x)), __FILE__, \
53 __LINE__, __func__, __comptime_as_str(y), \
54 ##__VA_ARGS__))
55
56#define panic(...) _panic_dispatch(CRASH_CODE_GENERIC, _panic, __VA_ARGS__)
57#define panic_with(payload, fmt, ...) \
58 panic_impl_default(payload, __FILE__, __LINE__, __func__, fmt, \
59 ##__VA_ARGS__)
60
61#define panic_with_default(default, ...) \
62 _panic_dispatch(default, _panic, __VA_ARGS__)
63