System Monitoring LVT Registers

Relevant source files

This document covers the system monitoring Local Vector Table (LVT) registers in the x86_vlapic implementation. These registers handle interrupts generated by thermal monitoring hardware and performance counter overflow events. System monitoring LVT registers are distinct from timer-based interrupts (see Timer LVT Register), external pin interrupts (see External Interrupt Pin Registers), and error condition interrupts (see Error Handling LVT Registers).

Overview

The x86_vlapic crate implements two system monitoring LVT registers that provide interrupt delivery for hardware monitoring subsystems:

  • Thermal Monitor Register: Handles thermal sensor threshold interrupts
  • Performance Counter Register: Handles performance monitoring unit (PMU) overflow and Intel Processor Trace (PT) interrupts

Both registers are implementation-specific extensions to the APIC architecture and share a common bit field structure for interrupt configuration.

System Monitoring LVT Architecture

System Monitoring LVT Register Structure

flowchart TD
subgraph INTERRUPT_SOURCES["Hardware Interrupt Sources"]
    MASK["Mask (16)"]
    THERMAL_SENSOR["Thermal Sensor Threshold Events"]
    PMU_OVERFLOW["Performance Counter Overflow"]
    INTEL_PT["Intel PT ToPA PMI"]
end
subgraph PERFMON["Performance Counter Register (0x340)"]
    PERFMON_BITFIELDS["LVT_PERFORMANCE_COUNTER Bitfields"]
    PERFMON_MMIO["LvtPerformanceCounterRegisterMmio"]
    PERFMON_LOCAL["LvtPerformanceCounterRegisterLocal"]
end
subgraph THERMAL["Thermal Monitor Register (0x330)"]
    VECTOR["Vector (0-7)"]
    DELIVERY_MODE["DeliveryMode (8-10)"]
    DELIVERY_STATUS["DeliveryStatus (12)"]
    THERMAL_BITFIELDS["LVT_THERMAL_MONITOR Bitfields"]
    THERMAL_MMIO["LvtThermalMonitorRegisterMmio"]
    THERMAL_LOCAL["LvtThermalMonitorRegisterLocal"]
end
subgraph COMMON["Common Bit Structure"]
    VECTOR["Vector (0-7)"]
    DELIVERY_MODE["DeliveryMode (8-10)"]
    DELIVERY_STATUS["DeliveryStatus (12)"]
    MASK["Mask (16)"]
    THERMAL_MMIO["LvtThermalMonitorRegisterMmio"]
    THERMAL_LOCAL["LvtThermalMonitorRegisterLocal"]
    THERMAL_SENSOR["Thermal Sensor Threshold Events"]
end

PERFMON_LOCAL --> PERFMON_BITFIELDS
PERFMON_MMIO --> PERFMON_BITFIELDS
THERMAL_LOCAL --> THERMAL_BITFIELDS
THERMAL_MMIO --> THERMAL_BITFIELDS

Sources: src/regs/lvt/thermal.rs(L1 - L74)  src/regs/lvt/perfmon.rs(L1 - L75) 

Thermal Monitor Register

The LVT Thermal Monitor Register at offset 0x330 delivers interrupts when thermal monitoring hardware detects temperature threshold violations. This register is implementation-specific and always located at base address FEE0 0330H when implemented.

Register Definition

The thermal monitor register is defined using the LVT_THERMAL_MONITOR bitfield structure:

FieldBitsDescription
Vector0-7Interrupt vector number
DeliveryMode8-10Interrupt delivery type
DeliveryStatus12Read-only delivery status
Mask16Interrupt enable/disable

Thermal Interrupt Conditions

The thermal monitor generates interrupts when:

  • Processor temperature exceeds configured thresholds
  • Thermal control circuit (TCC) activation occurs
  • Temperature monitoring hardware detects critical conditions

Register Types

The crate provides two access patterns for the thermal monitor register:

  • LvtThermalMonitorRegisterMmio: Direct MMIO access using ReadWrite<u32, LVT_THERMAL_MONITOR::Register>
  • LvtThermalMonitorRegisterLocal: Cached local copy using LocalRegisterCopy<u32, LVT_THERMAL_MONITOR::Register>

Sources: src/regs/lvt/thermal.rs(L5 - L66)  src/regs/lvt/thermal.rs(L68 - L73) 

Performance Counter Register

The LVT Performance Counter Register at offset 0x340 handles interrupts from performance monitoring units and Intel Processor Trace events. This register is implementation-specific and not guaranteed to be at the documented base address.

Register Definition

The performance counter register uses the LVT_PERFORMANCE_COUNTER bitfield structure with identical bit layout to the thermal monitor register:

FieldBitsDescription
Vector0-7Interrupt vector number
DeliveryMode8-10Interrupt delivery type
DeliveryStatus12Read-only delivery status
Mask16Interrupt enable/disable

Performance Monitoring Interrupt Sources

The performance counter register delivers interrupts for:

  1. Performance Counter Overflow: When hardware performance counters exceed their configured limits
  2. Intel PT ToPA PMI: Performance Monitoring Interrupt (PMI) signals from Intel Processor Trace Table of Physical Addresses (ToPA) mechanism

Register Types

Similar to the thermal register, two access patterns are provided:

  • LvtPerformanceCounterRegisterMmio: Direct MMIO access using ReadWrite<u32, LVT_PERFORMANCE_COUNTER::Register>
  • LvtPerformanceCounterRegisterLocal: Cached local copy using LocalRegisterCopy<u32, LVT_PERFORMANCE_COUNTER::Register>

Sources: src/regs/lvt/perfmon.rs(L5 - L66)  src/regs/lvt/perfmon.rs(L68 - L74) 

Common Bit Field Structure

Both system monitoring registers share identical bit field definitions, providing consistent configuration interfaces across different monitoring subsystems.

System Monitoring Register Bit Fields

flowchart TD
subgraph REG32["32-bit Register Layout"]
    FIXED["Fixed = 000"]
    IDLE["Idle = 0"]
    NOT_MASKED["NotMasked = 0"]
    RESERVED2["Reserved2(17-31)"]
    MASK_BIT["Mask(16)"]
    RESERVED1["Reserved1(13-15)"]
    DELIVERY_STATUS_BIT["DeliveryStatus(12)"]
    RESERVED0["Reserved0(11)"]
    DELIVERY_MODE_BITS["DeliveryMode(8-10)"]
    VECTOR_BITS["Vector(0-7)"]
end
subgraph MODE_VALUES["Delivery Mode Values"]
    FIXED["Fixed = 000"]
    SMI["SMI = 010"]
    NMI["NMI = 100"]
    RESERVED_MODE["Reserved = 110"]
    IDLE["Idle = 0"]
    SEND_PENDING["SendPending = 1"]
    NOT_MASKED["NotMasked = 0"]
    MASKED["Masked = 1"]
    RESERVED2["Reserved2(17-31)"]
    subgraph MASK_VALUES["Mask Field Values"]
        subgraph STATUS_VALUES["Delivery Status Values"]
            FIXED["Fixed = 000"]
            SMI["SMI = 010"]
            IDLE["Idle = 0"]
            SEND_PENDING["SendPending = 1"]
            NOT_MASKED["NotMasked = 0"]
            MASKED["Masked = 1"]
            RESERVED2["Reserved2(17-31)"]
        end
    end
end

Sources: src/regs/lvt/thermal.rs(L10 - L16)  src/regs/lvt/perfmon.rs(L10 - L16)  src/regs/lvt/thermal.rs(L30 - L56)  src/regs/lvt/perfmon.rs(L30 - L56) 

Delivery Mode Restrictions

System monitoring LVT registers have specific delivery mode restrictions compared to other LVT registers:

ModeBinarySupport Status
Fixed000✅ Supported
SMI010✅ Supported
NMI100✅ Supported
INIT101❌ Not supported
Reserved110❌ Not supported
ExtINT111❌ Not supported

The INIT and ExtINT delivery modes are explicitly not supported for thermal monitor and performance counter registers.

Sources: src/regs/lvt/thermal.rs(L44 - L45)  src/regs/lvt/perfmon.rs(L44 - L45)  src/regs/lvt/thermal.rs(L54 - L55)  src/regs/lvt/perfmon.rs(L54 - L55) 

Register Access Patterns

System monitoring LVT registers support both direct MMIO access and cached local copy patterns using the tock-registers framework.

LVT System Monitoring Register Access Architecture

sequenceDiagram
    participant GuestOS as "Guest OS"
    participant EmulatedLocalApic as "EmulatedLocalApic"
    participant VirtualApicRegs as "VirtualApicRegs"
    participant MMIORegister as "MMIO Register"
    participant LocalCopy as "Local Copy"

    Note over GuestOS,LocalCopy: Thermal Monitor Access (0x330)
    GuestOS ->> EmulatedLocalApic: "MMIO Read/Write FEE0_0330H"
    EmulatedLocalApic ->> VirtualApicRegs: "handle_read/write(ApicRegOffset::LvtThermal)"
    alt Direct MMIO Access
        VirtualApicRegs ->> MMIORegister: "LvtThermalMonitorRegisterMmio::read/write"
        MMIORegister -->> VirtualApicRegs: "LVT_THERMAL_MONITOR register value"
    else Cached Local Access
        VirtualApicRegs ->> LocalCopy: "LvtThermalMonitorRegisterLocal::read/write"
        LocalCopy -->> VirtualApicRegs: "Cached LVT_THERMAL_MONITOR value"
    end
    Note over GuestOS,LocalCopy: Performance Counter Access (0x340)
    GuestOS ->> EmulatedLocalApic: "MMIO Read/Write FEE0_0340H"
    EmulatedLocalApic ->> VirtualApicRegs: "handle_read/write(ApicRegOffset::LvtPerformanceCounter)"
    alt Direct MMIO Access
        VirtualApicRegs ->> MMIORegister: "LvtPerformanceCounterRegisterMmio::read/write"
        MMIORegister -->> VirtualApicRegs: "LVT_PERFORMANCE_COUNTER register value"
    else Cached Local Access
        VirtualApicRegs ->> LocalCopy: "LvtPerformanceCounterRegisterLocal::read/write"
        LocalCopy -->> VirtualApicRegs: "Cached LVT_PERFORMANCE_COUNTER value"
    end

Sources: src/regs/lvt/thermal.rs(L66 - L73)  src/regs/lvt/perfmon.rs(L66 - L74)