|
| 1 | +#include "irq_trace.h" |
| 2 | +#include <task/multi_task.h> |
| 3 | +#include <stdint.h> |
| 4 | +#include <util/console.h> |
| 5 | + |
| 6 | +static irq_trace_entry_t irq_trace_buf[IRQ_TRACE_CAPACITY]; |
| 7 | +static volatile unsigned irq_trace_head = 0; // next write index |
| 8 | + |
| 9 | +// IRQ-safe minimal record: no allocation, no printk |
| 10 | +void irq_trace_record(uint64_t vec, uint64_t rip, uint64_t rsp, uint64_t cr3, |
| 11 | + uint64_t rflags, uint32_t tid) { |
| 12 | + unsigned idx = irq_trace_head++; |
| 13 | + idx &= (IRQ_TRACE_CAPACITY - 1); |
| 14 | + irq_trace_buf[idx].vec = vec; |
| 15 | + irq_trace_buf[idx].rip = rip; |
| 16 | + irq_trace_buf[idx].rsp = rsp; |
| 17 | + irq_trace_buf[idx].cr3 = cr3; |
| 18 | + irq_trace_buf[idx].rflags = rflags; |
| 19 | + irq_trace_buf[idx].tid = tid; |
| 20 | +} |
| 21 | + |
| 22 | +// regs_stack layout assumed by irq stubs: see irq_stubs.asm |
| 23 | +// index 15 = RIP, index 17 = RFLAGS. RSP we record as pointer-based value |
| 24 | +void irq_trace_record_from_stack(uint64_t *regs_stack, uint32_t vec) { |
| 25 | + uint64_t rip = regs_stack[15]; |
| 26 | + uint64_t rflags = regs_stack[17]; |
| 27 | + // saved RSP pointer: caller's code in IRQ handler will expect saved RSP |
| 28 | + uint64_t rsp_ptr = (uint64_t)(®s_stack[15]); |
| 29 | + |
| 30 | + uint64_t cr3_val = 0; |
| 31 | + asm volatile("mov %%cr3, %0" : "=r"(cr3_val)); |
| 32 | + |
| 33 | + uint32_t tid = 0; |
| 34 | + task_t *t = task_current(); |
| 35 | + if (t) |
| 36 | + tid = t->tid; |
| 37 | + |
| 38 | + irq_trace_record(vec, rip, rsp_ptr, cr3_val, rflags, tid); |
| 39 | +} |
| 40 | + |
| 41 | +// Dump the buffer using printk — call only from non-IRQ context |
| 42 | +void irq_trace_dump(void) { |
| 43 | + printk("--- IRQ trace dump (last %d entries) ---\n", |
| 44 | + IRQ_TRACE_CAPACITY); |
| 45 | + unsigned start = (irq_trace_head >= IRQ_TRACE_CAPACITY) ? |
| 46 | + (irq_trace_head & (IRQ_TRACE_CAPACITY - 1)) : |
| 47 | + 0; |
| 48 | + unsigned count = (irq_trace_head >= IRQ_TRACE_CAPACITY) ? |
| 49 | + IRQ_TRACE_CAPACITY : |
| 50 | + irq_trace_head; |
| 51 | + for (unsigned i = 0; i < count; ++i) { |
| 52 | + unsigned idx = (start + i) & (IRQ_TRACE_CAPACITY - 1); |
| 53 | + irq_trace_entry_t *e = &irq_trace_buf[idx]; |
| 54 | + printk("[%3u] vec=%u tid=%u rip=0x%lx rsp=0x%lx cr3=0x%lx rflags=0x%lx\n", |
| 55 | + (unsigned)i, (unsigned)e->vec, (unsigned)e->tid, |
| 56 | + (unsigned long)e->rip, (unsigned long)e->rsp, |
| 57 | + (unsigned long)e->cr3, (unsigned long)e->rflags); |
| 58 | + } |
| 59 | +} |
0 commit comments