Register System

Relevant source files

This document provides comprehensive documentation of the virtual Local APIC register system implemented in the x86_vlapic crate. It covers all APIC registers, their memory layouts, address translation mechanisms, and access patterns for both xAPIC and x2APIC operating modes. For details about specific Local Vector Table register implementations, see Local Vector Table (LVT). For information about the higher-level device interface and virtualization architecture, see Core Architecture.

Register Organization Overview

The virtual LAPIC register system virtualizes the complete set of x86 Local APIC registers within a 4KB memory page. The system supports dual access modes: legacy xAPIC MMIO access and modern x2APIC MSR access, both mapping to the same underlying register state.

Register Address Translation

The system translates guest access addresses to internal register offsets using the ApicRegOffset enum, which serves as the canonical register identifier throughout the codebase.

flowchart TD
subgraph subGraph3["Physical Memory Layout"]
    LocalAPICRegs["LocalAPICRegs struct4KB tock-registers layout"]
end
subgraph subGraph2["Canonical Register Space"]
    ApicRegOffsetEnum["ApicRegOffset enumUnified register identifier"]
end
subgraph subGraph1["Address Translation Layer"]
    XAPICTranslate["xapic_mmio_access_reg_offset()GuestPhysAddr → ApicRegOffset"]
    X2APICTranslate["x2apic_msr_access_reg()SysRegAddr → ApicRegOffset"]
end
subgraph subGraph0["Guest Access Methods"]
    GuestMMIO["Guest xAPIC MMIO0xFEE00000-0xFEE00FFF"]
    GuestMSR["Guest x2APIC MSR0x800-0x8FF"]
end

ApicRegOffsetEnum --> LocalAPICRegs
GuestMMIO --> XAPICTranslate
GuestMSR --> X2APICTranslate
X2APICTranslate --> ApicRegOffsetEnum
XAPICTranslate --> ApicRegOffsetEnum

Sources: src/consts.rs(L200 - L202)  src/consts.rs(L213 - L215)  src/consts.rs(L61 - L114) 

Register Categories

The APIC register space is organized into several functional categories, each serving distinct purposes in interrupt handling and APIC management.

flowchart TD
subgraph subGraph5["APIC Register Categories"]
    subgraph subGraph2["Local Vector Table"]
        ICR_LOW["ICR_LO (0x300)Command Register Low"]
        ICR_HIGH["ICR_HI (0x310)Command Register High"]
        TIMER_INIT["ICR_TIMER (0x380)Initial Count"]
        TIMER_CUR["CCR_TIMER (0x390)Current Count"]
        TIMER_DIV["DCR_TIMER (0x3E0)Divide Configuration"]
        LVT_TIMER["LVT_TIMER (0x320)Timer Interrupt"]
        LVT_THERMAL["LVT_THERMAL (0x330)Thermal Monitor"]
        LVT_PMC["LVT_PMC (0x340)Performance Counter"]
        LVT_LINT1["LVT_LINT1 (0x360)External Pin 1"]
        LVT_ERROR["LVT_ERROR (0x370)Error Interrupt"]
        LVT_CMCI["LVT_CMCI (0x2F0)Corrected Machine Check"]
        ISR["ISR Array (0x100-0x170)In-Service Registers8 x 128-bit"]
        TMR["TMR Array (0x180-0x1F0)Trigger Mode Registers8 x 128-bit"]
        IRR["IRR Array (0x200-0x270)Interrupt Request Registers8 x 128-bit"]
        ID["ID (0x20)Local APIC Identifier"]
        VERSION["VERSION (0x30)APIC Version Info"]
        TPR["TPR (0x80)Task Priority"]
        subgraph subGraph0["Control Registers"]
            LVT_LINT0["LVT_LINT0 (0x350)External Pin 0"]
            SVR["SVR (0xF0)Spurious Interrupt Vector"]
            subgraph subGraph4["Interrupt Command"]
                ICR_LOW["ICR_LO (0x300)Command Register Low"]
                ICR_HIGH["ICR_HI (0x310)Command Register High"]
                TIMER_INIT["ICR_TIMER (0x380)Initial Count"]
                TIMER_CUR["CCR_TIMER (0x390)Current Count"]
                LVT_TIMER["LVT_TIMER (0x320)Timer Interrupt"]
                LVT_THERMAL["LVT_THERMAL (0x330)Thermal Monitor"]
                ISR["ISR Array (0x100-0x170)In-Service Registers8 x 128-bit"]
                TMR["TMR Array (0x180-0x1F0)Trigger Mode Registers8 x 128-bit"]
                ID["ID (0x20)Local APIC Identifier"]
                VERSION["VERSION (0x30)APIC Version Info"]
            end
            subgraph subGraph3["Timer Subsystem"]
                ICR_LOW["ICR_LO (0x300)Command Register Low"]
                ICR_HIGH["ICR_HI (0x310)Command Register High"]
                TIMER_INIT["ICR_TIMER (0x380)Initial Count"]
                TIMER_CUR["CCR_TIMER (0x390)Current Count"]
                TIMER_DIV["DCR_TIMER (0x3E0)Divide Configuration"]
                LVT_TIMER["LVT_TIMER (0x320)Timer Interrupt"]
                LVT_THERMAL["LVT_THERMAL (0x330)Thermal Monitor"]
                LVT_PMC["LVT_PMC (0x340)Performance Counter"]
                ISR["ISR Array (0x100-0x170)In-Service Registers8 x 128-bit"]
                TMR["TMR Array (0x180-0x1F0)Trigger Mode Registers8 x 128-bit"]
                IRR["IRR Array (0x200-0x270)Interrupt Request Registers8 x 128-bit"]
                ID["ID (0x20)Local APIC Identifier"]
                VERSION["VERSION (0x30)APIC Version Info"]
                TPR["TPR (0x80)Task Priority"]
            end
        end
    end
    subgraph subGraph1["Interrupt State Arrays"]
        LVT_LINT0["LVT_LINT0 (0x350)External Pin 0"]
        SVR["SVR (0xF0)Spurious Interrupt Vector"]
        subgraph subGraph4["Interrupt Command"]
            ICR_LOW["ICR_LO (0x300)Command Register Low"]
            ICR_HIGH["ICR_HI (0x310)Command Register High"]
            TIMER_INIT["ICR_TIMER (0x380)Initial Count"]
            TIMER_CUR["CCR_TIMER (0x390)Current Count"]
            LVT_TIMER["LVT_TIMER (0x320)Timer Interrupt"]
            LVT_THERMAL["LVT_THERMAL (0x330)Thermal Monitor"]
            ISR["ISR Array (0x100-0x170)In-Service Registers8 x 128-bit"]
            TMR["TMR Array (0x180-0x1F0)Trigger Mode Registers8 x 128-bit"]
            ID["ID (0x20)Local APIC Identifier"]
            VERSION["VERSION (0x30)APIC Version Info"]
        end
        subgraph subGraph3["Timer Subsystem"]
            ICR_LOW["ICR_LO (0x300)Command Register Low"]
            ICR_HIGH["ICR_HI (0x310)Command Register High"]
            TIMER_INIT["ICR_TIMER (0x380)Initial Count"]
            TIMER_CUR["CCR_TIMER (0x390)Current Count"]
            TIMER_DIV["DCR_TIMER (0x3E0)Divide Configuration"]
            LVT_TIMER["LVT_TIMER (0x320)Timer Interrupt"]
            LVT_THERMAL["LVT_THERMAL (0x330)Thermal Monitor"]
            LVT_PMC["LVT_PMC (0x340)Performance Counter"]
            ISR["ISR Array (0x100-0x170)In-Service Registers8 x 128-bit"]
            TMR["TMR Array (0x180-0x1F0)Trigger Mode Registers8 x 128-bit"]
            IRR["IRR Array (0x200-0x270)Interrupt Request Registers8 x 128-bit"]
            ID["ID (0x20)Local APIC Identifier"]
            VERSION["VERSION (0x30)APIC Version Info"]
            TPR["TPR (0x80)Task Priority"]
        end
    end
end

Sources: src/consts.rs(L61 - L114)  src/regs/mod.rs(L15 - L104) 

Address Translation Implementation

The ApicRegOffset enum provides a unified addressing scheme that abstracts the differences between xAPIC and x2APIC access patterns.

ApicRegOffset Enum Structure

Register CategoryOffset RangeApicRegOffset Variants
Control Registers0x2-0xFID,Version,TPR,APR,PPR,EOI,RRR,LDR,DFR,SIVR
Interrupt Arrays0x10-0x27ISR(ISRIndex),TMR(TMRIndex),IRR(IRRIndex)
Error Status0x28ESR
LVT Registers0x2F, 0x32-0x37LvtCMCI,LvtTimer,LvtThermal,LvtPmc,LvtLint0,LvtLint1,LvtErr
Interrupt Command0x30-0x31ICRLow,ICRHi
Timer Registers0x38-0x39, 0x3ETimerInitCount,TimerCurCount,TimerDivConf

Sources: src/consts.rs(L61 - L114)  src/consts.rs(L116 - L148) 

Index Enums for Register Arrays

The system uses generated index enums for the three 256-bit interrupt state arrays, each comprising 8 128-bit registers.

flowchart TD
subgraph subGraph2["Usage in ApicRegOffset"]
    ISRVariant["ApicRegOffset::ISR(ISRIndex)"]
    TMRVariant["ApicRegOffset::TMR(TMRIndex)"]
    IRRVariant["ApicRegOffset::IRR(IRRIndex)"]
end
subgraph subGraph1["Array Index Generation"]
    MacroGenerate["define_index_enum! macroGenerates 0-7 indices"]
    subgraph subGraph0["Generated Enums"]
        ISRIndex["ISRIndexISRIndex0-ISRIndex7"]
        TMRIndex["TMRIndexTMRIndex0-TMRIndex7"]
        IRRIndex["IRRIndexIRRIndex0-IRRIndex7"]
    end
end

IRRIndex --> IRRVariant
ISRIndex --> ISRVariant
MacroGenerate --> IRRIndex
MacroGenerate --> ISRIndex
MacroGenerate --> TMRIndex
TMRIndex --> TMRVariant

Sources: src/consts.rs(L3 - L54)  src/consts.rs(L56 - L58) 

Memory Layout Implementation

The LocalAPICRegs struct defines the physical memory layout using the tock-registers crate, providing type-safe register access with appropriate read/write permissions.

Register Access Patterns

Access TypeUsageExamples
ReadWriteConfigurable control registersID,TPR,LDR,DFR,ESR
ReadOnlyStatus and version registersVERSION,APR,PPR,RRD,CCR_TIMER
WriteOnlyCommand registersEOI,SELF_IPI
ReadOnlyInterrupt state arraysISR,TMR,IRRarrays
LVT Register TypesSpecialized LVT registersLvtTimerRegisterMmio,LvtThermalMonitorRegisterMmio, etc.

Sources: src/regs/mod.rs(L15 - L104) 

Reset Values and Constants

The system defines standardized reset values for APIC registers according to the x86 specification:

ConstantValuePurpose
RESET_LVT_REG0x0001_0000Default LVT register state with interrupt masked
RESET_SPURIOUS_INTERRUPT_VECTOR0x0000_00FFDefault spurious interrupt vector configuration

Sources: src/consts.rs(L183 - L190) 

Access Mode Implementation

The register system supports both xAPIC and x2APIC access modes through dedicated translation functions.

xAPIC MMIO Access

flowchart TD
subgraph subGraph0["xAPIC MMIO Translation"]
    MMIOAddr["Guest Physical Address0xFEE00000 + offset"]
    MMIOTranslate["xapic_mmio_access_reg_offset()(addr & 0xFFF) >> 4"]
    MMIOConstants["DEFAULT_APIC_BASE: 0xFEE00000APIC_MMIO_SIZE: 0x1000"]
    MMIOResult["ApicRegOffset enum value"]
end

MMIOAddr --> MMIOTranslate
MMIOConstants --> MMIOTranslate
MMIOTranslate --> MMIOResult

Sources: src/consts.rs(L192 - L202) 

x2APIC MSR Access

flowchart TD
subgraph subGraph0["x2APIC MSR Translation"]
    MSRAddr["System Register Address0x800-0x8FF range"]
    MSRTranslate["x2apic_msr_access_reg()addr - 0x800"]
    MSRConstants["X2APIC_MSE_REG_BASE: 0x800X2APIC_MSE_REG_SIZE: 0x100"]
    MSRResult["ApicRegOffset enum value"]
end

MSRAddr --> MSRTranslate
MSRConstants --> MSRTranslate
MSRTranslate --> MSRResult

Sources: src/consts.rs(L205 - L216) 

Register Structure Organization

The complete register system provides a comprehensive virtualization of Local APIC functionality, supporting interrupt handling, inter-processor communication, and timer operations through a unified, type-safe interface that abstracts the complexities of dual-mode APIC access.

Sources: src/consts.rs(L1 - L217)  src/regs/mod.rs(L1 - L105)