Pada artikel ini, saya ingin mempertimbangkan mekanisme pengiriman interupsi dari perangkat eksternal dalam sistem x86 dan mencoba menjawab pertanyaan:
- Apa itu PIC dan untuk apa?
- Apa itu APIC dan untuk apa? Untuk apa LAPIC dan I / O APIC?
- Apa perbedaan antara APIC, xAPIC dan x2APIC?
- Apa itu MSI? Apa perbedaan antara MSI dan MSI-X?
- Bagaimana tabel $ PIR, MPtable, ACPI terkait dengan ini?
Jika Anda tertarik menerima jawaban untuk semua pertanyaan ini atau jika Anda hanya ingin membiasakan diri dengan evolusi pengontrol interupsi dalam sistem x86, selamat datang di cat.
Pendahuluan
Kita semua tahu apa itu gangguan. Bagi yang bukan, kutipan dari wikipedia:
Gangguan (Bahasa Inggris interupsi) - sinyal dari perangkat lunak atau perangkat keras yang menginformasikan prosesor tentang terjadinya peristiwa apa pun yang membutuhkan perhatian segera. Gangguan memberitahu prosesor tentang terjadinya peristiwa prioritas tinggi yang memerlukan gangguan kode saat ini yang dijalankan oleh prosesor. Prosesor merespons dengan menangguhkan aktivitasnya saat ini, menyimpan keadaannya dan menjalankan fungsi yang disebut pengendali interupsi (atau interrupt handler) yang merespons peristiwa dan layanan itu, setelah itu mengembalikan kontrol ke kode yang terputus.
Tergantung pada sumber sinyal interupsi, mereka dibagi menjadi:
- asynchronous, atau eksternal (perangkat keras) - peristiwa yang berasal dari perangkat perangkat keras eksternal (seperti perangkat periferal) dan dapat terjadi kapan saja secara sewenang-wenang: sinyal dari timer, kartu jaringan atau drive disk, penekanan tombol, gerakan mouse. Fakta bahwa gangguan seperti itu terjadi dalam sistem ditafsirkan sebagai permintaan interupsi (IRQ) - perangkat melaporkan bahwa mereka memerlukan perhatian dari OS;
- peristiwa sinkron atau internal pada prosesor itu sendiri sebagai akibat dari pelanggaran kondisi tertentu ketika menjalankan kode mesin: pembagian dengan nol atau stack overflow, akses ke alamat memori yang tidak valid atau kode operasi yang tidak valid;
Pada artikel ini, saya ingin membahas interupsi IRQ eksternal.
Mengapa mereka dibutuhkan? Misalkan kita ingin melakukan beberapa tindakan dengan paket input untuk kartu jaringan ketika tiba. Agar tidak meminta kartu jaringan terus-menerus "apakah Anda memiliki paket baru?" dan jangan sia-siakan sumber daya prosesor untuk hal ini, Anda dapat menggunakan interupsi IRQ. Jalur interupsi perangkat terhubung ke jalur INTR prosesor, dan ketika sebuah paket diterima, kartu jaringan "menarik" garis ini. Prosesor mengerti bahwa ada informasi untuknya dan membaca paket.
Tetapi bagaimana jika ada banyak perangkat? Anda tidak bisa mendapatkan cukup dari semua perangkat eksternal dari kaki prosesor.

Untuk mengatasi masalah ini, mereka datang dengan sebuah chip - sebuah pengontrol interupsi.
Foto
(
wiki /
osdev )
Yang pertama adalah chip
Intel 8259 PIC . 8 jalur input (IRQ0-7), dan satu output menghubungkan controller dengan jalur INTR prosesor. Ketika interupsi dari suatu perangkat terjadi, 8259 menarik garis INTR, prosesor memahami bahwa beberapa perangkat memberi sinyal interupsi dan mensurvei PIC untuk memahami kaki IRQx yang menyebabkan interupsi. Ada penundaan tambahan untuk survei ini, tetapi jumlah garis interupsi meningkat menjadi 8.

Namun, 8 baris dengan cepat berubah menjadi kecil, dan untuk menambah jumlahnya, 2 8259 controller (master dan slave) yang terhubung dalam cascade (Dual PIC) digunakan.
IRQ 0 hingga 7 diproses oleh Intel 8259 PIC (master) pertama, dan IRQs 8 hingga 15 diproses oleh 8259 PIC kedua (slave). Hanya master yang memberi sinyal terjadinya interupsi. Jika interupsi terjadi pada baris 8-15, PIC kedua (slave) memberi sinyal interupsi ke master melalui IRQ 2, dan master pada gilirannya memberi sinyal CPU. Interupsi cascading ini mengambil salah satu dari 16 baris, tetapi pada akhirnya memberikan 15 interupsi yang tersedia untuk perangkat.

Sirkuit telah memantapkan dirinya, dan inilah yang mereka maksud ketika mereka berbicara tentang PIC (Programm Interrupt Controller) sekarang. Selanjutnya, pengendali 8259 menerima beberapa peningkatan, dan kemudian dikenal sebagai 8259A, dan sirkuit ini termasuk dalam chipset. Pada saat bus utama untuk menghubungkan perangkat eksternal adalah bus ISA, sistem seperti itu secara keseluruhan sudah cukup. Itu hanya perlu untuk memastikan bahwa perangkat yang berbeda tidak terhubung ke saluran IRQ yang sama untuk menghindari konflik, karena ISA menyela tidak dibagi.
Biasanya tata letak interupsi untuk perangkat lebih atau kurang standar
Contoh (diambil
dari sini ):
IRQ 0 - timer sistem
IRQ 1 - pengontrol keyboard
IRQ 2 - cascade (interupsi dari slave controller)
IRQ 3 - port serial COM2
IRQ 4 - port serial COM1
IRQ 5 - port paralel 2 dan 3 atau kartu suara
IRQ 6 - pengontrol floppy
IRQ 7 - port paralel 1
Penghitung waktu IRQ 8 - RTC
IRQ 9 - ACPI
IRQ 10 - terbuka / SCSI / NIC
IRQ 11 - terbuka / SCSI / NIC
IRQ 12 - pengendali mouse
IRQ 13 - co-prosesor matematika
IRQ 14 - saluran ATA 1
IRQ 15 - saluran ATA 2
Konfigurasi dan kerja dengan sirkuit mikro 8259 dilakukan melalui port I / O:
β Dokumentasi untuk 8259A dapat ditemukan di
sini.Bus ISA digantikan oleh bus PCI. Dan jumlah perangkat jelas mulai melebihi angka 15, ditambah, tidak seperti bus ISA statis, dalam hal ini, perangkat dapat ditambahkan ke sistem secara dinamis. Tapi untungnya di bus ini interupsi dapat dibagi (yaitu, beberapa perangkat dapat dihubungkan ke jalur IRQ yang sama). Akibatnya, untuk mengatasi masalah kurangnya jalur IRQ, mereka memutuskan untuk mengelompokkan interupsi dari semua perangkat PCI ke dalam jalur PIRQ (Programmable Interrupt Request).
Katakanlah kita memiliki 4 jalur interupsi secara bebas pada pengontrol PIC, dan 20 perangkat PCI. Kami menggabungkan interupsi dari 5 perangkat per baris PIRQx dan menghubungkan garis PIRQx ke controller. Jika terjadi interupsi pada jalur PIRQx, prosesor harus menginterogasi semua perangkat yang terhubung ke jalur ini untuk memahami dari siapa datangnya interupsi, tetapi secara umum ini menyelesaikan masalah. Perangkat yang mengikat jalur interupsi PCI dalam jalur PIRQ sering disebut router PIR.
Dalam metode ini, Anda harus memastikan bahwa garis PIRQx tidak terhubung ke jalur IRQx di mana ISA menyela sudah dimulai (karena ini akan menyebabkan konflik), dan bahwa garis PIRQx seimbang (karena semakin banyak perangkat yang kami sambungkan ke jalur PIRQ yang sama, semakin banyak perangkat yang Anda butuhkan akan menginterogasi prosesor untuk memahami perangkat mana yang menyebabkan interupsi ini).
Catatan : perangkat PCI -> pemetaan PIR ditampilkan secara abstrak dalam gambar, karena sebenarnya ini agak lebih rumit. Pada kenyataannya, setiap perangkat PCI memiliki 4 jalur interupsi (INTA, INTB, INTC, INTD). Setiap perangkat PCI dapat memiliki hingga 8 fungsi, dan sekarang setiap fungsi memiliki satu interupsi INTx. INTx yang mana setiap fungsi perangkat akan menarik ditentukan oleh konfigurasi chipset.
Intinya, fungsi adalah blok logis yang terpisah. Misalnya, dalam satu perangkat PCI mungkin ada fungsi pengontrol Smbus, fungsi pengontrol SATA, fungsi jembatan LPC. Di sisi OS, setiap fungsi adalah perangkat terpisah dengan ruang konfigurasi PCI Config-nya sendiri.
OS mengirimkan informasi tentang rute interupsi pada BIOS pengontrol PIC menggunakan tabel $ PIR dan dengan mengisi 3Ch (INT_LN Interrupt Line (R / W)) dan register 3Dh (INT_PN Interrupt Pin (RO)) dari ruang konfigurasi PCI untuk setiap fungsi. Spesifikasi untuk tabel $ PIR sebelumnya
di situs web Microsoft , tetapi sekarang tidak ada lagi. Isi baris dari tabel $ PIR dapat dipahami dari
Spesifikasi PCI BIOS [4.2.2. Dapatkan Opsi Routing Interupsi PCI] atau baca
di siniApic
(
wiki ,
osdev )
Metode sebelumnya bekerja hingga sistem multiprosesor muncul. Faktanya adalah bahwa dalam perangkatnya PIC dapat mentransmisikan interupsi hanya ke satu prosesor utama. Tapi saya ingin agar prosesor pada penanganan interupsi seimbang. Solusi untuk masalah ini adalah antarmuka APIC baru (Advanced PIC).
Untuk setiap prosesor, pengontrol LAPIC khusus (APIC Lokal) ditambahkan dan pengontrol
I / O APIC ditambahkan untuk merutekan interupsi dari perangkat. Semua pengendali ini digabungkan dalam bus umum yang disebut APIC (sistem baru sekarang terhubung melalui bus sistem standar).
Ketika interupsi dari perangkat tiba di pin I / O APIC, pengontrol merutekan interupsi ke LAPIC dari salah satu prosesor. Kehadiran I / O APIC memungkinkan Anda untuk menyeimbangkan distribusi interupsi dari perangkat eksternal antar prosesor.
Chip APIC pertama adalah
82489DX , itu adalah chip terpisah yang menggabungkan LAPIC dan I / O APIC. Untuk membuat sistem 2 prosesor, 3 mikrosirkuit seperti itu diperlukan. 2 akan berfungsi sebagai LAPIC dan satu sebagai I / O APIC. Kemudian, fungsi LAPIC secara langsung dimasukkan dalam prosesor, dan fungsi I / O APIC dibingkai dalam chip 82093AA.
I / O APIC
82093AA berisi 24 pin input, dan arsitektur APIC dapat mendukung hingga 16 CPU. Untuk menjaga kompatibilitas dengan sistem yang lebih lama, 0 ~ 15 interupsi dialokasikan untuk interupsi ISA lama. Dan gangguan dari perangkat PCI mulai ditampilkan pada jalur IRQ 16-23. Sekarang mungkin untuk tidak memikirkan konflik interupsi dari perangkat ISA dan PCI. Juga, berkat peningkatan jumlah jalur interupsi gratis, juga dimungkinkan untuk meningkatkan jumlah saluran PIRQx.

Pemrograman I / O APIC dan LAPIC dilakukan melalui MMIO. Register LAPIC biasanya terletak di 0xFEE00000, register I / O APIC di 0xFE00000. Meskipun, pada prinsipnya, semua alamat ini dapat dikonfigurasi ulang.
Seperti dalam kasus PIC, awalnya, chip individu kemudian menjadi bagian dari chipset.
Selanjutnya, arsitektur APIC menerima modernisasi dan versi baru disebut xAPIC (x - extended). Kompatibilitas mundur yang dipertahankan dengan versi sebelumnya. Jumlah CPU yang mungkin dalam sistem meningkat menjadi 256.
Putaran pengembangan arsitektur selanjutnya disebut
x2APIC . Jumlah CPU yang mungkin dalam sistem meningkat menjadi 2 ^ 32. Pengontrol dapat bekerja dalam mode kompatibilitas xAPIC, atau dalam mode x2APIC baru, di mana pemrograman LAPIC dilakukan bukan melalui MMIO, tetapi melalui register MSR (yang jauh lebih cepat). Dilihat
oleh tautan ini, dukungan IOMMU diperlukan agar mode ini berfungsi.
Perlu dicatat bahwa sistem mungkin memiliki beberapa pengontrol APIC I / O. Misalnya, satu untuk 24 gangguan di jembatan selatan, yang lain untuk 32 di utara. Dalam konteks I / O APIC interupsi sering disebut sebagai GSI (Global System Interrupt). Jadi dalam sistem seperti itu akan menjadi GSI 0-55.
Apakah ada built-in LAPIC di CPU dan arsitektur mana yang dapat dipahami oleh flag bit di CPUID.
Agar sistem mendeteksi LAPIC dan I / O APIC, BIOS harus memberikan informasi tentang mereka ke sistem baik melalui MPtable (metode lama) atau melalui tabel ACPI (MADT dalam kasus ini). Selain informasi umum, MPtable dan ACPI (kali ini dalam tabel DSDT) harus berisi informasi tentang perutean interupsi, yaitu, informasi tentang perangkat mana yang berada pada garis interupsi (mirip dengan tabel $ PIR).
Tabel MPTable dapat ditemukan dalam
spesifikasi resmi. Sebelumnya, spesifikasinya ada di situs web Intel, tetapi sekarang hanya dapat ditemukan di arsip. Spesifikasi ACPI sekarang terletak di situs web UEFI (versi
6.2 saat ini). Perlu dicatat bahwa menggunakan ACPI Anda dapat menentukan perutean interupsi untuk sistem tanpa APIC (daripada menggunakan tabel $ PIR).
Msi
(
wiki )
Versi sebelumnya dengan APIC bagus, tetapi bukan tanpa cacat. Semua jalur interupsi perangkat ini memperumit sirkuit dan meningkatkan kemungkinan kesalahan. Bus PCI digantikan oleh PCI express, di mana jalur interupsi diputuskan untuk dihapus. Untuk menjaga kompatibilitas, sinyal interupsi (INTx #) ditiru oleh jenis pesan tertentu. Dalam skema ini, penambahan logis garis interupsi, yang dulu dilakukan dengan koneksi fisik kabel, jatuh di pundak jembatan PCI. Namun, dukungan interupsi legacy INTx hanya mendukung kompatibilitas mundur dengan bus PCI. Bahkan, PCI express telah mengusulkan metode baru untuk mengirimkan pesan interupsi - MSI (Message Signaled Interrupts). Dalam metode ini, untuk memberi sinyal gangguan, perangkat cukup menulis ke area MMIO yang dialokasikan untuk LAPIC prosesor.

Sebelumnya, hanya 4 interupsi yang dialokasikan untuk satu perangkat PCI (yaitu, untuk semua fungsinya), tetapi sekarang telah menjadi mungkin untuk mengatasi hingga 32 interupsi.
Dalam kasus MSI, tidak ada pembagian untuk saluran, masing-masing interupsi sesuai dengan perangkatnya.
MSI menyela juga memecahkan masalah lain. Misalkan perangkat melakukan transaksi penulisan-memori, dan ingin melaporkan penyelesaiannya melalui interupsi. Tetapi transaksi tulis mungkin tertunda di bus selama proses transfer (yang tidak diketahui perangkat sama sekali), dan sinyal interupsi akan tiba sebelum prosesor. Dengan demikian, CPU masih akan membaca data yang tidak valid. Jika MSI digunakan, informasi tentang MSI ditransmisikan serta data, dan tidak akan dapat datang lebih awal.
Perlu dicatat bahwa interupsi MSI tidak dapat bekerja tanpa LAPIC, tetapi menggunakan MSI dapat menggantikan kami dengan I / O APIC (penyederhanaan desain).
Selanjutnya, metode ini menerima ekstensi MSI-X. Sekarang setiap perangkat dapat memiliki hingga 2048 interupsi. Dan menjadi mungkin untuk menunjukkan secara individual untuk setiap interupsi pada prosesor mana yang harus dieksekusi. Ini bisa sangat berguna untuk perangkat yang banyak dimuat seperti kartu jaringan.
Tidak diperlukan tabel BIOS tambahan untuk dukungan MSI. Tetapi perangkat harus melaporkan dukungan MSI di salah satu Kemampuan dalam PCI Config-nya, dan driver perangkat harus mendukung bekerja dengan MSI.
Kesimpulan
Dalam artikel ini, kami memeriksa evolusi pengendali interupsi, dan menerima informasi teoretis umum tentang pengiriman interupsi dari perangkat eksternal dalam sistem x86.
Pada bagian
selanjutnya, kita akan melihat bagaimana menggunakan di Linux masing-masing pengendali yang dijelaskan dalam praktek.
Referensi: