# CPU подсистема: концептуальная модель ## Состав и ответственность CPU подсистема отвечает за: 1. **Обработку прерываний и исключений** — IDT, обработчики. 2. **Исключения ранней загрузки** — пока ядро ещё не полностью инициализировано. 3. **TLB Shootdown** — межпроцессорное прерывание для синхронизации TLB. 4. **Local APIC** — программируемый контроллер прерываний. ``` CPU Subsystem ┌─────────────────────────────────────────────────────────┐ │ CPU Core #0 │ │ │ │ ┌──────────────┐ ┌─────────────────────────┐ │ │ │ LAPIC │ │ IDT │ │ │ │ │ │ │ │ │ │ ICR ────────┼────────► 0: #DE (Divide Error) │ │ │ │ EOI │ │ 1: #DB (Debug) │ │ │ │ (timer) │ │ ... │ │ │ │ │ │ 8: #DF (Double Fault) │ │ │ │ │ │ 13: #GP (GPF) │ │ │ │ │ │ 14: #PF (Page Fault) │ │ │ │ │ │ ... │ │ │ │ │ │ 0xFD: TLB Shootdown │ │ │ └──────────────┘ └─────────────────────────┘ │ └─────────────────────────────────────────────────────────┘ ``` ## Модули | Файл | Компонент | Функция | |------|-----------|---------| | `idt.rs` | IDT структуры | Определение IdtEntry, IdtPtr, InterruptDescriptorTable | | `interrupts.rs` | Обработчики | Early handlers, Page Fault, Double Fault, GPF, TLB shootdown | | `lapic.rs` | Local APIC | Инициализация LAPIC, EOI, broadcast IPI | ## Порядок инициализации ``` kmain() │ ├── cpu::interrupts::init_early_exceptions() │ └── IDT для векторов 0-31 + TLB shootdown (0xFD) │ ├── ... (PMM, LAPIC, Page tables) ... │ ├── cpu::interrupts::init_idt() │ └── Перезагрузка IDT с полными обработчиками │ ├── STI (разрешение прерываний) │ └── ... (работа с прерываниями) ``` ## Обработка исключений: два этапа ### Этап 1: Early (до VMM) На раннем этапе загрузки (до настройки page tables и heap) ядро не может обрабатывать сложные исключения. Для векторов 0-31 устанавливаются `early_handler_N`, которые: 1. Пушат вектор и (возможно) dummy error code. 2. Переходят в `early_common`. 3. Сохраняют все регистры. 4. Вызывают `rust_early_exception_handler(vector, error_code)`. 5. Паникуют (HALT). ### Этап 2: Полный (после VMM) После инициализации VMM три критических исключения получают полноценные обработчики: - **Page Fault (#PF, вектор 14)**: попытка обработать (COW, lazy). - **Double Fault (#DF, вектор 8)**: HALT с сообщением. - **General Protection Fault (#GPF, вектор 13)**: HALT с сообщением. - **TLB Shootdown (вектор 0xFD)**: межпроцессорный TLB сброс. ## TLB Shootdown: модель При изменении page tables на одном ядре, TLB других ядер устаревает. Протокол: ``` CPU 0 (инициатор) CPU 1 (мишень) │ │ ├── local_tlb_flush_asid() │ ├── SHOOTDOWN_LOCK.lock() │ ├── SHOOTDOWN_ASID = asid │ ├── SHOOTDOWN_ACK = 0 │ ├── LAPIC: broadcast IPI │ │ (вектор TLB_SHOOTDOWN_VECTOR) ───► прерывание! │ ├── handle_tlb_shootdown_ipi() │ ├── local_tlb_flush_asid() │ ├── SHOOTDOWN_ACK |= 1 << core │ ├── LAPIC::send_eoi() │ └── iretq │ │ ├── spin_loop() ◄────────────────────┤ │ (ждёт ACK от всех ядер) │ ├── SHOOTDOWN_LOCK.unlock() │ └── continue │ ```