Files
Deshab-OS/CODE/UTSM/kernel/log.c
T

79 lines
2.2 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.
#include <utsm/log.h>
/* ---- 内存日志缓冲区(实机启动日志持久化) ----
* 默认启用捕获:所有日志同时写串口和内存缓冲。
* 块设备就绪后由 disk_log_flush() 把缓冲区写入 FAT32 文件
* SYSTEM/DESHAB64/DEV/BOOTLOG.TXT(DEV 缺失时回退根目录 BOOTLOG.TXT)。 */
#define LOG_BUF_SIZE 524288u /* 512KB, 覆盖 LBA 2-1000 (999 扇区 ~500KB) */
static char g_log_buf[LOG_BUF_SIZE];
static u32 g_log_len = 0;
static int g_log_capture_on = 1;
void log_capture_enable(int enable) {
g_log_capture_on = enable;
}
const char *log_get_buffer(void) {
return g_log_buf;
}
u32 log_get_length(void) {
return g_log_len;
}
static void log_emit(const char *s) {
/* Phase7: 日志行临界区——抢占可能把一行日志切成两半(串口与
* BOOTLOG 缓冲都会花),pushfq/popfq 保存并恢复本上下文的 IF。 */
u64 flags;
__asm__ volatile("pushfq; popq %0; cli" : "=r"(flags) :: "memory");
serial_write(s);
if (g_log_capture_on && s) {
while (*s) {
if (g_log_len < LOG_BUF_SIZE) {
g_log_buf[g_log_len++] = *s;
}
s++;
}
}
/* BUG-GP-IRET: 只恢复 IF,不做全量 popfq。全量 popfq 会把进入本
* 函数前 flags 里的历史污染位(如 NT=1)原样写回 RFLAGS 并在上下文
* 间传播(NT=1 时下一次 iretq 直接 #GP(0))。本临界区的语义仅仅是
* "保存并恢复 IF"。 */
if (flags & (1ULL << 9)) { /* 恢复进入前的 IF */
__asm__ volatile("sti" ::: "memory");
}
}
static void log_line(const char *level, const char *msg) {
log_emit(level);
log_emit(" ");
log_emit(msg);
log_emit("\n");
}
void log_info(const char *msg) {
log_line("[INFO]", msg);
}
void log_warn(const char *msg) {
log_line("[WARN]", msg);
}
void log_error(const char *msg) {
log_line("[ERR ]", msg);
}
void log_hex64(const char *prefix, u64 value) {
static const char hex[] = "0123456789abcdef";
char buf[19];
buf[0] = '0';
buf[1] = 'x';
for (int i = 0; i < 16; i++) {
buf[2 + i] = hex[(value >> ((15 - i) * 4)) & 0xf];
}
buf[18] = 0;
log_emit(prefix);
log_emit(buf);
log_emit("\n");
}