182 lines
7.3 KiB
C
182 lines
7.3 KiB
C
/* instr.h — Deshab 统一插桩宏系统
|
||
*
|
||
* 提供四级插桩原语:
|
||
* INSTR_LOG — 带级别和模块过滤的日志输出
|
||
* INSTR_STAT — 轻量级计数器 + 周期性摘要
|
||
* INSTR_PROBE — 环形探测缓冲写入(结构化事件记录)
|
||
* INSTR_TS — 时间戳标注(阶段耗时测量)
|
||
*
|
||
* 设计原则:
|
||
* - 禁用时零开销: g_instr_enabled=0 时所有宏展开为空操作
|
||
* - 热路径安全: STAT_INC 仅一条条件自增,PROBE 仅条件写入
|
||
* - 统一配置: 通过 FUCK [debug] 段控制开关与粒度
|
||
* - 标签编码: 4 字符 ASCII 编码为 u32,避免字符串比较
|
||
*
|
||
* 使用方式:
|
||
* 1. 在 kernel_main() 中调用 instr_init(&g_boot_cfg) 初始化
|
||
* 2. 各模块 #include <utsm/instr.h> 后使用 INSTR_* 宏
|
||
* 3. 在 FUCK 中设置 [debug] enabled=1 开启插桩
|
||
*/
|
||
#ifndef UTSM_INSTR_H
|
||
#define UTSM_INSTR_H
|
||
|
||
#include <utsm/types.h>
|
||
|
||
/* ---- 日志级别 ---- */
|
||
#define INSTR_LOG_TRACE 0
|
||
#define INSTR_LOG_DEBUG 1
|
||
#define INSTR_LOG_INFO 2
|
||
#define INSTR_LOG_WARN 3
|
||
#define INSTR_LOG_ERROR 4
|
||
#define INSTR_LOG_SILENT 5
|
||
|
||
/* ---- 全局配置变量 (instr.c 定义) ---- */
|
||
extern u32 g_instr_enabled; /* 全局插桩开关,FUCK debug.enabled */
|
||
extern u32 g_instr_log_level; /* 日志级别阈值,FUCK debug.log_level */
|
||
extern u32 g_instr_probe_enable; /* 探测缓冲开关,FUCK debug.probe_enable */
|
||
extern u32 g_instr_stat_interval; /* 统计摘要间隔,FUCK debug.stat_summary_interval */
|
||
extern u32 g_instr_module_flags; /* 模块级过滤位掩码 */
|
||
|
||
/* ---- 模块标志位 ---- */
|
||
#define INSTR_F_UTSM_TRACE (1u << 0)
|
||
#define INSTR_F_VMM_TRACE (1u << 1)
|
||
#define INSTR_F_DKM_TRACE (1u << 2)
|
||
#define INSTR_F_DSK_TRACE (1u << 3)
|
||
#define INSTR_F_BLOCK_TRACE (1u << 4)
|
||
#define INSTR_F_NET_TRACE (1u << 5)
|
||
#define INSTR_F_INPUT_TRACE (1u << 6)
|
||
|
||
/* ---- INSTR_LOG: 带级别和模块过滤的日志 ----
|
||
* level: INSTR_LOG_TRACE/DEBUG/INFO/WARN/ERROR
|
||
* mod_flag: INSTR_F_xxx 或 0(不过滤)
|
||
* msg: 常量字符串
|
||
*
|
||
* 仅当 g_instr_enabled && level >= g_instr_log_level &&
|
||
* (mod_flag==0 || mod_flag & g_instr_module_flags) 时输出。
|
||
*/
|
||
#define INSTR_LOG(level, mod_flag, msg) do { \
|
||
if (g_instr_enabled && (level) >= g_instr_log_level && \
|
||
((mod_flag) == 0 || (g_instr_module_flags & (mod_flag)))) { \
|
||
if ((level) <= INSTR_LOG_ERROR) log_error(msg); \
|
||
else if ((level) <= INSTR_LOG_WARN) log_warn(msg); \
|
||
else log_info(msg); \
|
||
} \
|
||
} while(0)
|
||
|
||
/* ---- INSTR_STAT: 轻量级计数器 (声明+增量+摘要) ----
|
||
* INSTR_STAT_DECL(name) — 在函数/文件作用域声明计数器
|
||
* INSTR_STAT_INC(name) — 原子性自增 (仅当 enabled)
|
||
* INSTR_STAT_SUMMARY(name) — 达到间隔时输出摘要并重置
|
||
*/
|
||
#define INSTR_STAT_DECL(name) \
|
||
static u64 name##_count = 0; \
|
||
static u64 name##_last_ts __attribute__((unused)) = 0
|
||
|
||
#define INSTR_STAT_INC(name) do { \
|
||
if (g_instr_enabled) { name##_count++; } \
|
||
} while(0)
|
||
|
||
#define INSTR_STAT_SUMMARY(name) do { \
|
||
if (g_instr_enabled && name##_count >= g_instr_stat_interval) { \
|
||
u64 _now = instr_rdtsc(); \
|
||
u64 _elapsed_ms = (_now - name##_last_ts) / (instr_tsc_per_ms ? instr_tsc_per_ms : 1); \
|
||
log_info("[STAT] " #name " count="); \
|
||
log_hex64("", name##_count); \
|
||
log_info("[STAT] " #name " interval_ms="); \
|
||
log_hex64("", _elapsed_ms); \
|
||
name##_count = 0; \
|
||
name##_last_ts = _now; \
|
||
} \
|
||
} while(0)
|
||
|
||
/* ---- INSTR_PROBE: 写入环形探测缓冲 ----
|
||
* 标签编码: 4 字符 ASCII,如 "BOOT", "VME0", "EPTV", "IDTI", "AHCI"
|
||
* a0-a3: 4 个 u64 参数,语义由标签定义
|
||
*
|
||
* 仅当 g_instr_enabled && g_instr_probe_enable 时写入。
|
||
*/
|
||
#define INSTR_PROBE(tag, a0, a1, a2, a3) do { \
|
||
if (g_instr_enabled && g_instr_probe_enable) \
|
||
probe_write(INSTR_TAG_##tag, (u64)(a0), (u64)(a1), (u64)(a2), (u64)(a3)); \
|
||
} while(0)
|
||
|
||
/* ---- INSTR_TS: 时间戳标注(阶段耗时测量) ----
|
||
* INSTR_TS_DECL(name) — 声明时间戳变量
|
||
* INSTR_TS_BEGIN(name) — 记录起始 TSC
|
||
* INSTR_TS_END(name, label) — 计算耗时并输出(仅当 enabled)
|
||
*/
|
||
#define INSTR_TS_DECL(name) static u64 name##_ts = 0
|
||
|
||
#define INSTR_TS_BEGIN(name) do { name##_ts = instr_rdtsc(); } while(0)
|
||
|
||
#define INSTR_TS_END(name, label) do { \
|
||
if (g_instr_enabled) { \
|
||
u64 _d = instr_rdtsc() - name##_ts; \
|
||
u64 _ms = _d / (instr_tsc_per_ms ? instr_tsc_per_ms : 1); \
|
||
log_info("[TS] " label " elapsed_ms="); \
|
||
log_hex64("", _ms); \
|
||
} \
|
||
} while(0)
|
||
|
||
/* ---- 标签编码常量 ----
|
||
* 4 字符 ASCII 编码为大端序 u32:
|
||
* 'B'=0x42, 'O'=0x4F, 'O'=0x4F, 'T'=0x54 → 0x424F4F54
|
||
*/
|
||
#define INSTR_TAG_BOOT 0x424F4F54u /* "BOOT" — 通用启动事件 */
|
||
#define INSTR_TAG_IDT0 0x49445430u /* "IDT0" — IDT/中断初始化 */
|
||
#define INSTR_TAG_ARE0 0x41524530u /* "ARE0" — Arena 初始化 */
|
||
#define INSTR_TAG_DMA0 0x444D4130u /* "DMA0" — DMA 初始化 */
|
||
#define INSTR_TAG_NET0 0x4E455430u /* "NET0" — 网络注册 */
|
||
#define INSTR_TAG_DRR0 0x44525230u /* "DRR0" — DRR 初始化 */
|
||
#define INSTR_TAG_UTS0 0x55545330u /* "UTS0" — UTSM 核心初始化 */
|
||
#define INSTR_TAG_DKM0 0x444B4D30u /* "DKM0" — DKM 加载 */
|
||
#define INSTR_TAG_DSM0 0x44534D30u /* "DSM0" — 驱动 manifest 加载 */
|
||
#define INSTR_TAG_DSK0 0x44534B30u /* "DSK0" — DSK 加载跳转 */
|
||
#define INSTR_TAG_SELF 0x53454C46u /* "SELF" — 自检 */
|
||
#define INSTR_TAG_VMM0 0x564D4D30u /* "VMM0" — VMM 初始化 */
|
||
#define INSTR_TAG_LIN0 0x4C494E30u /* "LIN0" — Linux loader */
|
||
#define INSTR_TAG_VME0 0x564D4530u /* "VME0" — VM-Exit 事件 */
|
||
#define INSTR_TAG_EPTV 0x45505456u /* "EPTV" — EPT violation */
|
||
#define INSTR_TAG_EPTM 0x4550544Du /* "EPTM" — EPT misconfig */
|
||
#define INSTR_TAG_AHCI 0x41484349u /* "AHCI" — AHCI 事件 */
|
||
#define INSTR_TAG_E1K0 0x45314B30u /* "E1K0" — e1000 事件 */
|
||
#define INSTR_TAG_FAT0 0x46415430u /* "FAT0" — FAT32 事件 */
|
||
#define INSTR_TAG_NVM0 0x4E564D30u /* "NVM0" — NVMe 事件 */
|
||
#define INSTR_TAG_IRQ0 0x49525130u /* "IRQ0" — IRQ 注册/触发 */
|
||
#define INSTR_TAG_PIT0 0x50495430u /* "PIT0" — PIT 模拟 */
|
||
#define INSTR_TAG_SRL0 0x53524C30u /* "SRL0" — 串口事件 */
|
||
#define INSTR_TAG_MMIO 0x4D4D494Fu /* "MMIO" — MMIO 访问 */
|
||
#define INSTR_TAG_HCALL 0x4843414Cu /* "HCAL" — Hypercall */
|
||
#define INSTR_TAG_EXCP 0x45584350u /* "EXCP" — CPU 异常 */
|
||
|
||
/* ---- 探测条目结构(与 probe.c 共享) ---- */
|
||
typedef struct probe_entry {
|
||
u32 tag; /* 4字符ASCII标签 */
|
||
u32 tick; /* 低32位TSC(~2s溢出@2GHz,足够诊断) */
|
||
u64 args[4]; /* 4个u64参数 */
|
||
} probe_entry;
|
||
|
||
/* ---- 辅助函数声明 (instr.c / probe.c 定义) ---- */
|
||
u64 instr_rdtsc(void);
|
||
extern u64 instr_tsc_per_ms;
|
||
void instr_init(const void *ini_config);
|
||
|
||
void probe_init(const void *ini_config);
|
||
void probe_write(u32 tag, u64 a0, u64 a1, u64 a2, u64 a3);
|
||
int probe_read(u32 n, probe_entry *out);
|
||
u32 probe_count(void);
|
||
u32 probe_capacity(void);
|
||
probe_entry *probe_buf_address(void);
|
||
u32 probe_head_value(void);
|
||
u32 probe_dropped_count(void);
|
||
|
||
/* 需要前向声明 log 函数 (避免循环 include) */
|
||
#ifndef UTSM_LOG_H
|
||
void log_info(const char *msg);
|
||
void log_warn(const char *msg);
|
||
void log_error(const char *msg);
|
||
void log_hex64(const char *prefix, u64 value);
|
||
#endif
|
||
|
||
#endif /* UTSM_INSTR_H */
|