Przerwanie
Z Wikipedii
Przerwanie (ang. interrupt) lub żądanie przerwania (IRQ - Interrupt ReQuest) – sygnał powodujący zmianę przepływu sterowania, niezależnie od aktualnie wykonywanego programu. Pojawienie się przerwania powoduje wstrzymanie aktualnie wykonywanego programu i wykonanie przez procesor kodu procedury obsługi przerwania (ang. interrupt handler).
Spis treści |
[edytuj] Rodzaje przerwań
Przerwania dzielą się na dwie grupy:
- Sprzętowe:
- Zewnętrzne – sygnał przerwania pochodzi z zewnętrznego układu obsługującego przerwania sprzętowe; przerwania te służą do komunikacji z urządzeniami zewnętrznymi, np. z klawiaturą, napędami dysków itp.
- Wewnętrzne, nazywane wyjątkami (ang. exceptions) – zgłaszane przez procesor dla sygnalizowania sytuacji wyjątkowych (np. dzielenie przez zero); dzielą się na trzy grupy:
- faults (niepowodzenie) – sytuacje, w których aktualnie wykonywana instrukcja powoduje błąd; gdy procesor powraca do wykonywania przerwanego kodu wykonuje następną, po tej która wywołała wyjątek, instrukcję;
- traps (pułapki) – sytuacja, która nie jest błędem, jej wystąpienie ma na celu wykonanie określonego kodu; wykorzystywane przede wszystkim w debugerach; gdy procesor powraca do wykonywania przerwanego kodu, wykonuje tę samą instrukcję która wywołała wyjątek;
- aborts – błędy, których nie można naprawić.
- Programowe – z kodu programu wywoływana jest procedura obsługi przerwania; najczęściej wykorzystywane do komunikacji z systemem operacyjnym, który w procedurze obsługi przerwania (np. w DOS 21h, 2fh, Windows 2fh, Linux x86 przerwanie 80h) umieszcza kod wywołujący odpowiednie funkcje systemowe w zależności od zawartości rejestrów ustawionych przez program wywołujący, lub oprogramowaniem wbudowanym jak procedury BIOS lub firmware.
Producenci procesorów część pozycji w tablicy wektorów przerwań rezerwują dla przerwań wewnętrznych. Pozostałe numery przerwań mogą być dowolnie wykorzystane przez producentów systemów komputerowych i oprogramowania. Obsługiwanie większości przerwań (wszystkich lub wybranych numerów) można wstrzymać lub zablokować, wyjątkiem są przerwania niemaskowalne.
[edytuj] Opis procesorów rodziny x86
[edytuj] Tryb rzeczywisty
W trybie rzeczywistym (ang. real) pracy procesora adres procedury obsługi przerwania jest zapisany w tablicy wektorów przerwań. Tablica wektorów przerwań przechowuje adresy poszczególnych procedur obsługi przerwań; przerwania identyfikowane są przez numer (wektor przerwania) i w przypadku procesorów serii x86 jest możliwych do 256 przerwań.
Tablica wektorów przerwań znajduje się w pierwszych 1024 (256 4 Bajtowych adresów procedur obsługi przerwań) komórkach pamięci operacyjnej.
W komputerach PC jest zazwyczaj 16(sic!-15 wynika to z kaskadowego połączenia dwóch kontrolerów przerwań) różnych sygnałów IRQ (ang. interrupt request) – IRQ0 do IRQ15. Często mówiąc o IRQ ma się na myśli sam numer przerwania, jako zasób udostępniany przez procesor. Jako, że jest ich tylko 16, bywają problemy z przydzieleniem osobnego przerwania każdemu z urządzeń, które go potrzebuje, może to powodować przydzielenie tego samego przerwania dwóm urządzeniom. Mówi się wtedy o konflikcie przerwań, gdyż najczęściej dwa urządzenia nie mogą współdzielić jednego.
[edytuj] Tryb chroniony
W trybie chronionym (ang. protected) pracy procesora x86 (od procesora i386) mamy do czynienia z tablicą deskryptorów przerwań (ang. Interrupt Descriptor Table, IDT) łączącą każdy wektor wyjątku lub przerwania z deskryptorem bramy (deskryptory bram to deskryptory pozwalające na kontrolowany dostęp do segmentów kodu o różnych stopniach uprzywilejowana) dla procedury lub zadania (ang. task) obsługującym dany wyjątek lub przerwanie.
Położenie IDT jest zapisane w rejestrze tablicy deskryptorów przerwań (ang. Interrupt Descriptor Table Register, IDTR). IDT zawiera do 256 wpisów zwanych deskryptorami. Rozmiar IDT to 256*8B (8 Bajtów to rozmiar pojedynczego deskryptora); w przypadku mniejszej ilości deskryptorów (obsługiwanych przerwań) niż maksymalne 256, puste sloty (czyli w rzeczywistości nieważne deskryptory) powinny zawierać flagę dostępności segmentu (ang. Segment Present Flag, P) ustawioną na 0 (zobacz budowa deskryptora).
IDT może zawierać trzy różne rodzaje deskryptorów bram:
- deskryptor bramy zadania (ang. Task-Gate Descriptor)
- deskryptor bramy przerwania (ang. Interrupt-Gate Descriptor)
- deskryptor bramy pułapki (ang. Trap-Gate Descriptor)
[edytuj] Przerwania w PowerPC
Gdy wystąpi przerwanie:
- Procesor czeka aż wcześniejsze instrukcje (będące w potoku) zostaną ukończone (procesor wykonuje instrukcje w niezmienionym kontekście tj. przy niezmienionym rejestrze MSR <<ang. Machine State Register>>).
- Mechanizm przerwania hardware’owo zapisuje adres następnej instrukcji do rejestru SRR0 (ang. Save/Restore Register), a rejestr MSR kopiuje do rejestru SRR1 (niektóre bity rejestru SRR1 są także zapisywane na podstawie typu przerwania, które nastąpiło).
- Nowa wartość dla rejestru MSR jest wpisywana (na podstawie typu przerwania, które nastąpiło). MSR[IR] i MSR[DR] są wyzerowane dla każdego typu przerwania, czyli translacja adresów zarówno dla instrukcji i danych jest zawsze wyłączona w czasie obsługi przerwania. Bit MSR[ILE] jest kopiowany do MSR[LE] (wyrób trybu pracy procesora: MSR[LE]=0 big-endian mode albo MSR[LE]=1 little-endian mode). Obsługa przerwania odbywa się w trybie nadzorcy (ang. supervisor mode).
- Bit MSR[RI] jest wyzerowany. MSR[RI]=0 oznacza, że program obsługi przerwania jest w trakcie inicjacji i w momencie nastąpienia kolejnego przerwania pierwsze przerwanie będzie nadpisane (innymi słowy gdy MSR[RI]=0, to przerwanie jest nieodzyskiwalne <<ang. not recoverable>>).
- Gdy program obsługi przerwania zapisze na stosie SRR0 oraz SRR1, a wskaźnik stosu zostanie zaktualizowany, bit MSR[RI] jest ustawiany na 1 przez program obsługi przerwania. Ustawienie MSR[RI]=1 oznacza, że procesor może przyjąć kolejne przerwanie bez utraty poprzedniego (ang. recoverable exception).
- Procesor wykonuje pierwszą instrukcję procedury obsługi przerwania zgodnie z nową wartością rejestru MSR. Początek procedury obsługi przerwania jest wyliczany na podstawie typu przerwania (ang. vector offset) oraz bitu MSR[ME] (MSR[ME]=0 adres fizyczny 0x000n_nnnn, MSR[ME]=1 0xFFFn_nnnn).
- Powrót do przerwanego programu za pomocą instrukcji rfi (ang. return from interrupt). Instrukcja rfi wykonuje synchronizację kontekstu (ang. context synchronization).
Przerwania dzieli się na klasy: precyzyjne/nieprecyzyjne (ang. precise/imprecise), synchroniczne/asynchroniczne oraz maskowalne/niemaskowalne. Każdemu przerwaniu przypisywany jest priorytet. Najwyższy priorytet mają przerwania ‘System reset’ (priorytet 1) i ‘Machine check’ (priorytet 2). Oba przerwania należą do asynchronicznych i niemaskowalnych. W związku z najwyższym priorytetem obsługa tych przerwań nie będzie nigdy opóźniona. Ponieważ pojedyncza instrukcja może wywołać więcej niż jedno przerwanie (przerwanie precyzyjne, synchroniczne z priorytetem 3), to kolejność ich obsługi jest ściśle określona w zależności od typu instrukcji (np. instrukcje odczytu i ładowania liczb stałoprzecinkowych mają tą samą kolejność).
Pozostałe priorytety są następujące:
4 – przerwania nieprecyzyjne, np. przerwania od jednostki zmiennoprzecinkowej
5 – przerwania maskowalne, nieprecyzyjne, asynchroniczne, np. przerwanie zewnętrzne (ang. external)
6 - przerwania maskowalne, nieprecyzyjne, asynchroniczne, np. decrementer