Core Trap Handling Framework
Relevant source files
Purpose and Scope
The Core Trap Handling Framework provides a unified, cross-architecture mechanism for registering and dispatching trap handlers in axcpu. This framework enables external code to register handlers for interrupts, page faults, and system calls without needing to know architecture-specific details. The framework uses Rust's linkme crate to create distributed slices that collect handlers at link time.
For architecture-specific trap handling implementations, see x86_64 Trap and Exception Handling, AArch64 Trap and Exception Handling, RISC-V Trap and Exception Handling, and related sections. For user space system call support, see User Space Support.
Handler Registration Mechanism
The framework uses linkme::distributed_slice to create static collections of handler functions that are populated at link time. This allows modules throughout the codebase to register handlers without requiring explicit registration calls.
Handler Registration Architecture
flowchart TD
subgraph subGraph2["External Modules"]
EXT_IRQ["External IRQ Handler"]
EXT_PF["External Page Fault Handler"]
EXT_SYS["External Syscall Handler"]
end
subgraph subGraph1["Static Handler Collections"]
IRQ_SLICE["IRQ: [fn(usize) -> bool]"]
PF_SLICE["PAGE_FAULT: [fn(VirtAddr, PageFaultFlags, bool) -> bool]"]
SYSCALL_SLICE["SYSCALL: [fn(&TrapFrame, usize) -> isize]"]
end
subgraph subGraph0["Handler Registration"]
LINKME["linkme::distributed_slice"]
DEF_MACRO["def_trap_handler macro"]
REG_MACRO["register_trap_handler macro"]
end
DEF_MACRO --> IRQ_SLICE
DEF_MACRO --> PF_SLICE
DEF_MACRO --> SYSCALL_SLICE
EXT_IRQ --> IRQ_SLICE
EXT_PF --> PF_SLICE
EXT_SYS --> SYSCALL_SLICE
LINKME --> DEF_MACRO
LINKME --> REG_MACRO
Sources: src/trap.rs(L6 - L7) src/trap.rs(L11 - L22)
The framework exports two key macros:
def_trap_handler- Used internally to define handler collectionsregister_trap_handler- Used by external code to register handlers
Trap Types and Handler Signatures
The framework defines three primary trap types, each with specific handler signatures optimized for their use cases.
| Trap Type | Handler Signature | Purpose | Feature Gate |
|---|---|---|---|
| IRQ | fn(usize) -> bool | Hardware interrupt handling | Always available |
| PAGE_FAULT | fn(VirtAddr, PageFaultFlags, bool) -> bool | Memory access violations | Always available |
| SYSCALL | fn(&TrapFrame, usize) -> isize | System call handling | uspacefeature |
Trap Handler Details
flowchart TD
subgraph subGraph1["Page Fault Handler"]
SYS_FRAME["TrapFrame"]
SYS_RESULT["Return Value (isize)"]
PF_ADDR["Virtual Address"]
PF_USER["User Space (bool)"]
IRQ_NUM["IRQ Number (usize)"]
IRQ_RESULT["Handled (bool)"]
subgraph subGraph2["Syscall Handler"]
SYS_NUM["Syscall Number"]
PF_RESULT["Handled (bool)"]
PF_FLAGS["PageFaultFlags"]
subgraph subGraph0["IRQ Handler"]
SYS_FRAME["TrapFrame"]
SYS_RESULT["Return Value (isize)"]
PF_ADDR["Virtual Address"]
IRQ_NUM["IRQ Number (usize)"]
IRQ_RESULT["Handled (bool)"]
end
end
end
IRQ_NUM --> IRQ_RESULT
PF_ADDR --> PF_RESULT
PF_FLAGS --> PF_RESULT
PF_USER --> PF_RESULT
SYS_FRAME --> SYS_RESULT
SYS_NUM --> SYS_RESULT
Sources: src/trap.rs(L12) src/trap.rs(L16) src/trap.rs(L22)
Trap Dispatching Framework
The framework provides a unified dispatching mechanism through the handle_trap macro and specialized functions for different trap types.
Dispatch Mechanism
flowchart TD
subgraph subGraph1["Error Handling"]
MULTI_WARN["Multiple Handler Warning"]
NO_HANDLER["No Handler Warning"]
end
subgraph subGraph0["Trap Dispatch Flow"]
ARCH_TRAP["Architecture-Specific Trap Entry"]
HANDLE_MACRO["handle_trap! macro"]
HANDLER_LOOKUP["Handler Lookup"]
SINGLE_CHECK["Single Handler Check"]
HANDLER_CALL["Handler Function Call"]
end
subgraph subGraph2["Specialized Functions"]
SYSCALL_FUNC["handle_syscall()"]
DIRECT_CALL["Direct SYSCALL[0] call"]
end
ARCH_TRAP --> HANDLE_MACRO
HANDLER_LOOKUP --> NO_HANDLER
HANDLER_LOOKUP --> SINGLE_CHECK
HANDLE_MACRO --> HANDLER_LOOKUP
SINGLE_CHECK --> HANDLER_CALL
SINGLE_CHECK --> MULTI_WARN
SYSCALL_FUNC --> DIRECT_CALL
Sources: src/trap.rs(L25 - L38) src/trap.rs(L42 - L44)
Macro Implementation
The handle_trap macro provides a standardized way to dispatch to registered handlers:
- Retrieves the handler slice for the specified trap type
- Checks for exactly one registered handler
- Issues warnings for multiple or missing handlers
- Calls the handler with the provided arguments
System Call Specialization
System calls receive special handling through the handle_syscall function, which directly calls the first (and expected only) syscall handler without the overhead of the generic dispatch mechanism.
Sources: src/trap.rs(L41 - L44)
Integration with Architecture-Specific Code
The Core Trap Handling Framework serves as the interface between architecture-specific trap entry points and higher-level system components.
Architecture Integration Flow
flowchart TD
subgraph subGraph2["System Components"]
KERNEL["Kernel Services"]
DRIVER["Device Drivers"]
SYSCALL_SVC["System Call Service"]
end
subgraph subGraph1["Core Framework"]
TRAP_MACRO["handle_trap! macro"]
IRQ_HANDLERS["IRQ handler slice"]
PF_HANDLERS["PAGE_FAULT handler slice"]
SYS_HANDLERS["SYSCALL handler slice"]
end
subgraph subGraph0["Architecture Layer"]
X86_TRAP["x86_64 trap handlers"]
ARM_TRAP["aarch64 trap handlers"]
RISCV_TRAP["riscv trap handlers"]
LOONG_TRAP["loongarch64 trap handlers"]
end
ARM_TRAP --> TRAP_MACRO
IRQ_HANDLERS --> DRIVER
LOONG_TRAP --> TRAP_MACRO
PF_HANDLERS --> KERNEL
RISCV_TRAP --> TRAP_MACRO
SYS_HANDLERS --> SYSCALL_SVC
TRAP_MACRO --> IRQ_HANDLERS
TRAP_MACRO --> PF_HANDLERS
TRAP_MACRO --> SYS_HANDLERS
X86_TRAP --> TRAP_MACRO
Sources: src/lib.rs(L12) src/lib.rs(L15 - L27)
Type System Integration
The framework integrates with core axcpu types:
TrapFrame- Architecture-specific CPU state during trapsVirtAddr- Virtual memory addresses from thememory_addrcratePageFaultFlags- Memory access flags frompage_table_entrycrate
This type integration ensures that handlers receive properly structured data regardless of the underlying architecture.