Files
Deshab-OS/CODE/UTSM/include/utsm/instr.h
T
2026-07-31 13:53:49 +08:00

182 lines
7.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* 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 */