Interrupt Classification: SGI, PPI, SPI, LPI

Chapter 6 GICv3 Architecture and Interrupt Handling Practice

6.2 Interrupt Classification: SGI, PPI, SPI, LPI

6.2.1 Overview and Design Philosophy of Interrupt Classification

In the GICv3 architecture, interrupt sources are systematically categorized into four types based on the source of the interrupt, the distribution mechanism, and the characteristics of the target processor. Understanding the differences between these four types of interrupts is crucial for building an efficient and reliable interrupt handling system.

Core Design Principles of Interrupt Classification

Source-based Classification:

  • Software Generated Interrupts: Triggered explicitly by software for inter-processor communication.

  • Hardware Generated Interrupts: Triggered by physical devices, including private and shared peripherals.

  • Message Signal Interrupts: A modern interrupt mechanism based on memory write operations.

Target-based Classification:

  • Core Specific Interrupts: Interrupts targeted at specific processors.

  • Global Shared Interrupts: Interrupts that can be routed to any processor.

6.2.2 Software Generated Interrupts (SGI)

Basic Concepts and Characteristics of SGI

Software generated interrupts are interrupts explicitly triggered by software through writing to the GICD_SGIR register, primarily used for communication and synchronization between multi-core processors.

Key Features of SGI:

  • Interrupt ID Range: 0-15

  • Trigger Method: Triggered by software writing to registers.

  • Target Control: Can precisely specify one or more target processors.

  • Use Cases: Inter-core communication, task scheduling, cache consistency maintenance.

SGI Architectural Principles

The implementation of SGI is based on the software triggering mechanism of GICv3:

Interrupt Classification: SGI, PPI, SPI, LPI

SGI Register Configuration

// SGI related register definitions
typedef struct {
    // Software Generated Interrupt Register
    struct {
        uint32_t SGIID : 4;    // SGI Interrupt ID (0-15)
        uint32_t CPUTargetList : 8;  // Target processor list
        uint32_t TargetListFilter : 2; // Target list filter
        uint32_t RSVD : 18;    // Reserved bits
    } GICD_SGIR;
    // SGI Configuration Register
    volatile uint32_t GICD_ICFGR[2];  // SGI configuration (read-only, fixed to edge-triggered)
} gic_sgi_registers_t;

// SGI Target Filter Definitions
typedef enum {
    SGI_TARGET_SELF = 0x0,     // Send to current processor
    SGI_TARGET_LIST = 0x1,     // Send to specified processor list
    SGI_TARGET_OTHERS = 0x2,   // Send to all other processors
    SGI_TARGET_ALL = 0x3       // Send to all processors (including self)
} sgi_target_filter_t;

SGI Practical Code

SGI configuration and usage based on domestic Cortex-R52+ chip:

// SGI management and usage function
void sgi_management_system(void) {
    printf("=== SGI Management System Initialization ===\n");
    // 1. Configure all SGI interrupts
    configure_all_sgis();
    // 2. Register SGI handlers
    register_sgi_handlers();
    // 3. Test SGI functionality
    test_sgi_functionality();
    printf("SGI Management System Ready\n");
}

// Configure SGI interrupts
void configure_all_sgis(void) {
    printf("Configuring SGI interrupts...\n");
    for (int sgi_id = 0; sgi_id < 16; sgi_id++) {
        // Set SGI priority (medium priority)
        set_sgi_priority(sgi_id, 0x80);
        // Configure SGI targets (default to all processors)
        set_sgi_targets(sgi_id, 0xFF, SGI_TARGET_LIST);
        printf("SGI %d configuration complete - Priority: 0x%02X\n", sgi_id, 0x80);
    }
}

// Set SGI priority
void set_sgi_priority(uint32_t sgi_id, uint32_t priority) {
    if (sgi_id > 15) return;
    // SGI priority configured in redistributor
    uint32_t reg_index = sgi_id / 4;
    uint32_t shift = (sgi_id % 4) * 8;
    uint32_t mask = 0xFF << shift;
    uint32_t current = gicr->GICR_IPRIORITYR[reg_index];
    current &= ~mask;
    current |= (priority << shift);
    gicr->GICR_IPRIORITYR[reg_index] = current;
}

// Send SGI interrupt
void send_sgi(uint32_t sgi_id, uint32_t target_list, sgi_target_filter_t filter) {
    if (sgi_id > 15) {
        printf("Error: SGI ID %d out of range (0-15)\n", sgi_id);
        return;
    }
    // Build SGIR register value
    uint32_t sgir_value = (filter << 24) | (target_list << 16) | sgi_id;
    // Write to SGIR register to trigger SGI
    gicd->GICD_SGIR = sgir_value;
    printf("Sending SGI %d - Target: 0x%02X, Filter: %d\n",
            sgi_id, target_list, filter);
}

// Inter-core communication example
void inter_core_communication_example(void) {
    uint32_t core_id = get_cpu_id();
    if (core_id == 0) {
        // Core 0 sends task to Core 1
        printf("Core 0: Sending task to Core 1\n");
        // Prepare task data
        prepare_task_data();
        // Send SGI to notify Core 1
        send_sgi(SGI_TASK_NOTIFY, 0x02, SGI_TARGET_LIST); // Target is Core 1
    } else if (core_id == 1) {
        // Core 1 waits for task notification
        printf("Core 1: Waiting for task notification\n");
    }
}

// SGI handler
void sgi_handler(uint32_t sgi_id) {
    uint32_t core_id = get_cpu_id();
    printf("Core %d: Handling SGI %d\n", core_id, sgi_id);
    switch (sgi_id) {
        case SGI_TASK_NOTIFY:
            handle_task_notification();
            break;
        case SGI_CACHE_SYNC:
            handle_cache_synchronization();
            break;
        case SGI_SCHEDULE_YIELD:
            handle_schedule_yield();
            break;
        default:
            printf("Unknown SGI: %d\n", sgi_id);
            break;
    }
}

6.2.3 Private Peripheral Interrupts (PPI)

Basic Concepts and Characteristics of PPI

Private peripheral interrupts are interrupt sources that are private to each processor core, typically used for peripherals tightly coupled with specific processors.

Key Features of PPI:

  • Interrupt ID Range: 16-31

  • Privacy: Each processor has its own independent set of PPIs.

  • Typical Applications: Local timers, performance counters, watchdog timers.

  • Configuration Independence: Each processor can independently configure its own PPIs.

PPI Architectural Principles

The implementation of PPI reflects the independence of processors:

Interrupt Classification: SGI, PPI, SPI, LPI

PPI Interrupt Source Allocation

Typical PPI interrupt ID allocation:

// PPI interrupt ID definitions
typedef enum {
    PPI_MAINTENANCE_INTERRUPT = 16,    // Maintenance interrupt
    PPI_LOCAL_TIMER_INTERRUPT = 27,    // Local timer interrupt
    PPI_PERFORMANCE_MONITOR = 26,      // Performance monitor interrupt
    PPI_WATCHDOG_TIMER = 28,           // Watchdog timer interrupt
    PPI_LEGACY_FIQ = 28                // Legacy FIQ interrupt
} ppi_interrupt_id_t;

PPI Practical Code

// PPI management system
void ppi_management_system(void) {
    printf("=== PPI Management System Initialization ===\n");
    // 1. Configure local timer PPI
    configure_local_timer_ppi();
    // 2. Configure performance monitor PPI
    configure_performance_monitor_ppi();
    // 3. Configure watchdog PPI
    configure_watchdog_ppi();
    // 4. Register PPI handlers
    register_ppi_handlers();
    printf("PPI Management System Ready\n");
}

// Configure local timer PPI
void configure_local_timer_ppi(void) {
    printf("Configuring local timer PPI...\n");
    // Set priority (higher priority, ensure timely response)
    set_ppi_priority(PPI_LOCAL_TIMER_INTERRUPT, 0x40);
    // Configure as edge-triggered
    set_ppi_trigger_type(PPI_LOCAL_TIMER_INTERRUPT, TRIGGER_EDGE);
    // Enable PPI
    enable_ppi(PPI_LOCAL_TIMER_INTERRUPT);
    printf("Local timer PPI configuration complete\n");
}

// Configure PPI priority
void set_ppi_priority(uint32_t ppi_id, uint32_t priority) {
    if (ppi_id < 16 || ppi_id > 31) return;
    uint32_t reg_index = (ppi_id - 16) / 4;
    uint32_t shift = ((ppi_id - 16) % 4) * 8;
    uint32_t mask = 0xFF << shift;
    uint32_t current = gicr->GICR_IPRIORITYR[reg_index];
    current &= ~mask;
    current |= (priority << shift);
    gicr->GICR_IPRIORITYR[reg_index] = current;
}

// Configure PPI trigger type
void set_ppi_trigger_type(uint32_t ppi_id, trigger_type_t type) {
    if (ppi_id < 16 || ppi_id > 31) return;
    // PPI configuration in GICR_ICFGR1
    uint32_t bit_offset = (ppi_id - 16) * 2;
    uint32_t reg_value = gicr->GICR_ICFGR[1]; // GICR_ICFGR1
    // Clear existing configuration
    reg_value &= ~(0x3 << bit_offset);
    // Set new configuration
    reg_value |= (type << bit_offset);
    gicr->GICR_ICFGR[1] = reg_value;
}

// PPI handler
void ppi_handler(uint32_t ppi_id) {
    uint32_t core_id = get_cpu_id();
    printf("Core %d: Handling PPI %d\n", core_id, ppi_id);
    switch (ppi_id) {
        case PPI_LOCAL_TIMER_INTERRUPT:
            handle_local_timer_interrupt();
            break;
        case PPI_PERFORMANCE_MONITOR:
            handle_performance_monitor_interrupt();
            break;
        case PPI_WATCHDOG_TIMER:
            handle_watchdog_interrupt();
            break;
        default:
            printf("Unknown PPI: %d\n", ppi_id);
            break;
    }
}

// Local timer interrupt handling
void handle_local_timer_interrupt(void) {
    uint32_t core_id = get_cpu_id();
    // Handle timer events
    process_timer_events();
    // Reprogram timer
    reprogram_local_timer();
    printf("Core %d: Local timer interrupt handling complete\n", core_id);
}

6.2.4 Shared Peripheral Interrupts (SPI)

Basic Concepts and Characteristics of SPI

Shared peripheral interrupts are interrupts generated by external devices that can be routed to one or more processor cores, making them the most common type of interrupt in the system.

Key Features of SPI:

  • Interrupt ID Range: 32-1019

  • Shared Nature: Interrupts can be shared among multiple processors.

  • Typical Applications: Network devices, storage devices, USB devices.

  • Configuration Flexibility: Can be configured for load balancing and dynamic target selection.

SPI Architectural Principles

SPI achieves flexible routing through a distributor:

Interrupt Classification: SGI, PPI, SPI, LPI

SPI Routing Strategies

SPI supports various routing strategies:

// SPI routing configuration
typedef enum {
    ROUTE_ANY_CPU,          // Route to any available processor
    ROUTE_SPECIFIC_CPU,     // Route to specific processor
    ROUTE_CPU_GROUP,        // Route to processor group
    ROUTE_ALL_CPUS          // Route to all processors
} spi_routing_strategy_t;

// SPI target processor masks
#define CPU0_MASK   0x01
#define CPU1_MASK   0x02
#define CPU2_MASK   0x04
#define CPU3_MASK   0x08
#define ALL_CPUS    0x0F

SPI Practical Code

// SPI management system
void spi_management_system(void) {
    printf("=== SPI Management System Initialization ===\n");
    // 1. Configure common SPI interrupts
    configure_common_spi_interrupts();
    // 2. Configure device-specific SPI interrupts
    configure_device_spi_interrupts();
    // 3. Set SPI routing strategies
    configure_spi_routing_strategies();
    // 4. Register SPI handlers
    register_spi_handlers();
    printf("SPI Management System Ready\n");
}

// Configure SPI interrupt
void configure_spi(uint32_t spi_id, uint32_t priority, uint32_t target_cpus,
                    trigger_type_t trigger_type) {
    if (spi_id < 32 || spi_id > 1019) {
        printf("Error: SPI ID %d out of range (32-1019)\n", spi_id);
        return;
    }
    printf("Configuring SPI %d - Priority: 0x%02X, Target CPU: 0x%02X, Trigger Type: %s\n",
           spi_id, priority, target_cpus,
           trigger_type == TRIGGER_EDGE ? "Edge" : "Level");
    // Set priority
    set_spi_priority(spi_id, priority);
    // Set target processors
    set_spi_targets(spi_id, target_cpus);
    // Set trigger type
    set_spi_trigger_type(spi_id, trigger_type);
    // Enable SPI
    enable_spi(spi_id);
}

// Set SPI target processors
void set_spi_targets(uint32_t spi_id, uint32_t target_cpus) {
    uint32_t reg_index = spi_id / 4;
    uint32_t shift = (spi_id % 4) * 8;
    uint32_t mask = 0xFF << shift;
    uint32_t current = gicd->GICD_ITARGETSR[reg_index];
    current &= ~mask;
    current |= (target_cpus << shift);
    gicd->GICD_ITARGETSR[reg_index] = current;
}

// Load balancing SPI routing
void load_balance_spi_routing(uint32_t spi_id) {
    static uint32_t current_cpu = 0;
    uint32_t num_cpus = get_cpu_count();
    // Polling to select target processor
    uint32_t target_cpu = 1 << current_cpu;
    current_cpu = (current_cpu + 1) % num_cpus;
    set_spi_targets(spi_id, target_cpu);
    printf("SPI %d load balanced to CPU %d\n", spi_id, current_cpu);
}

// SPI handler
void spi_handler(uint32_t spi_id) {
    uint32_t core_id = get_cpu_id();
    printf("Core %d: Handling SPI %d\n", core_id, spi_id);
    // Dispatch to specific device handler based on SPI ID
    switch (spi_id) {
        case SPI_UART0:
            handle_uart0_interrupt();
            break;
        case SPI_ETH0:
            handle_ethernet_interrupt();
            break;
        case SPI_USB0:
            handle_usb_interrupt();
            break;
        case SPI_DMA0:
            handle_dma_interrupt();
            break;
        default:
            // Dynamic device handling
            handle_dynamic_device_interrupt(spi_id);
            break;
    }
}

// Network interrupt handling example
void handle_ethernet_interrupt(void) {
    uint32_t core_id = get_cpu_id();
    // Read network controller status
    eth_status_t status = read_ethernet_status();
    if (status.rx_packet_ready) {
        // Handle received data packet
        process_ethernet_rx_packet();
    }
    if (status.tx_packet_complete) {
        // Handle transmission completion
        process_ethernet_tx_complete();
    }
    // Re-enable interrupts
    enable_ethernet_interrupts();
    printf("Core %d: Network interrupt handling complete\n", core_id);
}

6.2.5 Location-based Special Peripheral Interrupts (LPI)

Basic Concepts and Characteristics of LPI

Location-based special peripheral interrupts are a new type of interrupt mechanism introduced by GICv3, using message signal interrupt mode, particularly suitable for modern high-speed peripherals.

Key Features of LPI:

  • Interrupt ID Range: 8192+

  • Private Nature: Each processor has its own independent set of LPIs.

  • Typical Applications: High-speed peripherals such as PCIe.

  • Configuration Independence: Each processor can independently configure its own LPIs.

LPI Architectural Principles

LPI employs a completely different implementation mechanism:

Interrupt Classification: SGI, PPI, SPI, LPI

LPI Configuration Data Structure

LPI uses data structures in memory for configuration:

// LPI configuration data structure
typedef struct {
    uint8_t priority;        // Priority
    uint8_t enable : 1;      // Enable bit
    uint8_t reserved : 7;    // Reserved bits
} lpi_config_entry_t;

// LPI pending state structure
typedef struct {
    uint8_t pending_bits[1024]; // Pending bitmap
} lpi_pending_table_t;

// ITS device table entry
typedef struct {
    uint64_t valid : 1;      // Valid bit
    uint64_t size : 5;       // Interrupt translation table size
    uint64_t base_address : 52; // Interrupt translation table base address
    uint64_t reserved : 6;   // Reserved bits
} its_device_table_entry_t;

LPI Practical Code

// LPI management system
void lpi_management_system(void) {
    printf("=== LPI Management System Initialization ===\n");
    // 1. Initialize LPI configuration table
    initialize_lpi_config_tables();
    // 2. Configure ITS (if supported)
    if (gic_supports_its()) {
        initialize_its();
    }
    // 3. Configure LPI redistributor
    configure_lpi_redistributor();
    // 4. Enable LPI support
    enable_lpi_support();
    printf("LPI Management System Ready\n");
}

// Initialize LPI configuration table
void initialize_lpi_config_tables(void) {
    printf("Initializing LPI configuration table...\n");
    // Allocate memory for LPI configuration table
    lpi_config_table = allocate_uncached_memory(LPI_CONFIG_TABLE_SIZE);
    if (!lpi_config_table) {
        printf("Error: Unable to allocate memory for LPI configuration table\n");
        return;
    }
    // Initialize all LPI entries to disabled state
    for (int i = 0; i < LPI_MAX_ENTRIES; i++) {
        lpi_config_table[i].enable = 0;
        lpi_config_table[i].priority = 0x80; // Default priority
    }
    // Set LPI configuration table base address
    gicr->GICR_PROPBASER = (uint64_t)lpi_config_table | GICR_PROPBASER_Valid;
    printf("LPI configuration table initialization complete - Base Address: 0x%016llX\n",
            (uint64_t)lpi_config_table);
}

// Configure LPI interrupt
void configure_lpi(uint32_t lpi_id, uint32_t priority, uint32_t target_cpu) {
    if (lpi_id < 8192) {
        printf("Error: LPI ID %d is invalid (must >= 8192)\n", lpi_id);
        return;
    }
    uint32_t table_index = lpi_id - 8192;
    if (table_index >= LPI_MAX_ENTRIES) {
        printf("Error: LPI ID %d exceeds configuration table range\n", lpi_id);
        return;
    }
    // Configure LPI entry
    lpi_config_table[table_index].priority = priority;
    lpi_config_table[table_index].enable = 1;
    // Flush cache to ensure configuration takes effect
    clean_dcache_range((uint32_t)&amp;lpi_config_table[table_index],
                       sizeof(lpi_config_entry_t));
    printf("LPI %d configuration complete - Priority: 0x%02X, Target CPU: %d\n",
           lpi_id, priority, target_cpu);
}

// Enable LPI support
void enable_lpi_support(void) {
    printf("Enabling LPI support...\n");
    // Enable redistributor LPI support
    gicr->GICR_CTLR |= GICR_CTLR_EnableLPIs;
    // Wait for enable to complete
    while (!(gicr->GICR_CTLR && GICR_CTLR_EnableLPIs));
    printf("LPI support enabled\n");
}

// PCIe device LPI configuration
void configure_pcie_device_lpi(uint32_t device_id, uint32_t lpi_base, uint32_t num_interrupts) {
    if (!gic_supports_its()) {
        printf("Error: System does not support ITS, cannot configure PCIe LPI\n");
        return;
    }
    printf("Configuring PCIe device %d LPI interrupt...\n", device_id);
    // Configure ITS device table
    configure_its_device_table(device_id, lpi_base, num_interrupts);
    // Configure interrupt translation table
    configure_its_interrupt_table(device_id, lpi_base, num_interrupts);
    // Enable device LPI
    enable_pcie_device_lpi(device_id);
    printf("PCIe device %d LPI configuration complete\n", device_id);
}

6.2.6 Summary of Interrupt Classification Comparison

Feature Comparison Analysis

Feature Dimension

SGI

PPI

SPI

LPI

Interrupt ID Range

0-15

16-31

32-1019

8192+

Trigger Method

Software write to register

Hardware signal

Hardware signal

Memory write operation

Target Control

Precise control

Fixed processor

Configurable routing

ITS routing

Configuration Storage

Registers

Registers

Registers

Memory table

Typical Applications

Inter-core communication

Local peripherals

Global peripherals

High-speed peripherals

Performance Characteristics

Low latency

Low latency

Medium latency

High scalability

Usage Scenario Guide

// Interrupt type selection guide
void interrupt_type_selection_guide(void) {
    printf("=== Interrupt Type Selection Guide ===\n");
    printf("Choose SGI when:\n");
    printf("  - Inter-processor communication is needed\n");
    printf("  - Task scheduling and synchronization are implemented\n");
    printf("  - Cache consistency needs to be maintained\n\n");
    printf("Choose PPI when:\n");
    printf("  - Interrupt source is tightly coupled with a specific processor\n");
    printf("  - Low-latency local interrupts are needed\n");
    printf("  - Using local timers or performance counters\n\n");
    printf("Choose SPI when:\n");
    printf("  - Interrupt source can be shared among multiple processors\n");
    printf("  - Dynamic load balancing is needed\n");
    printf("  - Connecting general external devices\n\n");
    printf("Choose LPI when:\n");
    printf("  - A large number of interrupt sources are needed\n");
    printf("  - Using modern high-speed peripherals (e.g., PCIe)\n");
    printf("  - Message signal interrupt support is needed\n");
}

6.2.7 Practical Interrupt Classification for Domestic Chips

Complete Interrupt System Configuration

Complete interrupt classification configuration based on domestic Cortex-R52+ chip:

// Complete interrupt system initialization
void complete_interrupt_system_init(void) {
    printf("=== Domestic Cortex-R52+ Complete Interrupt System Initialization ===\n");
    // 1. GICv3 basic initialization
    gicv3_init();
    // 2. Configure various interrupts
    sgi_management_system();
    ppi_management_system();
    spi_management_system();
    // 3. If LPI is supported, initialize LPI system
    if (gic_supports_lpi()) {
        lpi_management_system();
    }
    // 4. Configure interrupt routing policies
    configure_interrupt_routing_policies();
    // 5. Enable interrupt handling
    enable_interrupt_handling();
    printf("Complete interrupt system initialization complete\n");
}

// Interrupt routing policy configuration
void configure_interrupt_routing_policies(void) {
    printf("Configuring interrupt routing policies...\n");
    // SGI: Precise control routing
    configure_sgi_routing_policy();
    // PPI: Fixed routing to local processor
    configure_ppi_routing_policy();
    // SPI: Load balancing routing
    configure_spi_routing_policy();
    // LPI: ITS controlled routing (if supported)
    if (gic_supports_its()) {
        configure_lpi_routing_policy();
    }
    printf("Interrupt routing policy configuration complete\n");
}

// SPI load balancing routing policy
void configure_spi_routing_policy(void) {
    printf("Configuring SPI load balancing routing...\n");
    // Network device SPI - load balanced to all processors
    set_spi_targets(SPI_ETH0, ALL_CPUS);
    // Storage device SPI - fixed to CPU0 (reduce cache synchronization overhead)
    set_spi_targets(SPI_SATA0, CPU0_MASK);
    // USB device SPI - load balanced to CPU0 and CPU1
    set_spi_targets(SPI_USB0, CPU0_MASK | CPU1_MASK);
    printf("SPI load balancing routing configuration complete\n");
}

Functional Safety Interrupt Configuration

In ASIL D systems, interrupt configuration requires additional safety considerations:

// ASIL D interrupt safety configuration
void asil_d_interrupt_safety_configuration(void) {
    printf("=== ASIL D Interrupt Safety Configuration ===\n");
    // 1. Redundant configuration for critical interrupts
    configure_redundant_critical_interrupts();
    // 2. Integrity protection for interrupt configuration
    configure_interrupt_configuration_protection();
    // 3. Interrupt monitoring and diagnosis
    configure_interrupt_monitoring_diagnosis();
    // 4. Safety response mechanisms
    configure_safety_response_mechanisms();
    printf("ASIL D interrupt safety configuration complete\n");
}

// Redundant configuration for critical interrupts
void configure_redundant_critical_interrupts(void) {
    printf("Configuring redundant critical interrupts...\n");
    // Watchdog interrupt - configured to all processors
    set_spi_targets(SPI_WATCHDOG, ALL_CPUS);
    set_ppi_priority(PPI_WATCHDOG_TIMER, 0x00); // Highest priority
    // Safety monitoring interrupt - multi-path redundancy
    configure_redundant_safety_monitor_interrupts();
    // Critical communication interrupt - backup routing
    configure_backup_communication_interrupts();
    printf("Redundant critical interrupts configuration complete\n");
}

// Interrupt configuration integrity check
void interrupt_configuration_integrity_check(void) {
    static uint32_t last_check_time = 0;
    uint32_t current_time = read_system_timer();
    if (current_time - last_check_time > INTERRUPT_CHECK_INTERVAL) {
        // Check critical interrupt configurations
        if (!verify_critical_interrupt_configurations()) {
            log_safety_violation("Critical interrupt configurations modified");
            restore_critical_interrupt_configurations();
        }
        // Check interrupt routing configurations
        if (!verify_interrupt_routing_configurations()) {
            log_safety_violation("Interrupt routing configurations abnormal");
            reconfigure_interrupt_routing();
        }
        last_check_time = current_time;
    }
}

Conclusion

The four types of interrupts (SGI, PPI, SPI, LPI) in the GICv3 architecture provide refined interrupt management solutions for different application scenarios:

Core Classification Value

  1. SGI (Software Generated Interrupt):

  • Provides an efficient software triggering mechanism for multi-core communication.

  • Supports precise target processor control.

  • Suitable for task scheduling, cache consistency maintenance, and other scenarios.

  • PPI (Private Peripheral Interrupt):

    • Provides an independent interrupt environment for each processor.

    • Ensures low-latency access to local peripherals.

    • Suitable for timers, performance monitoring, and other core-specific functions.

  • SPI (Shared Peripheral Interrupt):

    • Provides a flexible routing mechanism for system peripherals.

    • Supports load balancing and dynamic target selection.

    • Suitable for shared devices such as networking and storage.

  • LPI (Location-based Special Peripheral Interrupt):

    • Provides a scalable interrupt solution for modern high-speed peripherals.

    • Uses message signal interrupt mode to reduce pin dependencies.

    • Suitable for devices like PCIe and high-speed networks.

    Practical Guidance Principles

    In the practical application of the domestic Cortex-R52+ chip:

    • Choose Interrupt Types Wisely: Select the appropriate interrupt type based on device characteristics and performance requirements.

    • Optimize Interrupt Routing: Utilize the load balancing capability of SPI to enhance system performance.

    • Ensure Critical Interrupt Reliability: Implement redundant configurations for safety-critical interrupts.

    • Monitor Interrupt System Health: Regularly check the integrity of interrupt configurations.

    By deeply understanding the characteristics and applicable scenarios of the four types of interrupts, developers can build efficient and reliable interrupt handling systems that meet the strict requirements for real-time performance and functional safety in fields such as automotive electronics and industrial control.

    Leave a Comment