MyToyOS: Interrrupções (complemento)

Uma coisa que esqueci de mencionar no artigo anterior é que o processador suporta dois estilos de interrupções: Existem as interrupções mascaráveis, ou seja, que podem ser desabilitadas, e uma única interrupção não mascarável ou NMI (Non Maskable Interrupt).

Nos PCs, a NMI geralmente é usada para eventos catastróficos de hardware ou, em muitos sistemas, não ser usada de forma alguma…

Quanto às interrupções mascaráveis, como vimos no artigo anterior, elas podem ser desabilitadas setando o bit correspondente na OCW1, do PIC… Note também que o processador tem um FLAG de habilitação de interrupções mascaráveis (flag IF) e ele é manipulado pelas instruções CLI e STI… A diferença desses métodos está no ponto onde as interrupções são “escondidas” do processador.

Na máscara em OCW1 podemos mascarar qualquer interrupção isoladamente. Por exemplo, podemos esconder a IRQ3, assim:

  in al,0x21      ; Lê a máscara do PIC1.
  or al,(1 shl 3) ; Seta a máscara para IRQ3.
  out 0x21,al     ; Escreve a nova máscara no PIC1.

E o processador jamais a receberá, até que a máscara seja retirada… No caso das instruções CLI e STI, todas as interrupções mascaráreis são desabilitadas ou habilitadas. Isso é útil nas rotinas de tratamento de interrupções porque evita que outras interrupções sejam aceitas pelo processador enquanto estamos tratando alguma, em curso… O PIC continuará pedindo interrupções, mas o processador simplesmente não as reconhecerá (o sinal INTA# não será ativado e o processamento normal não será interrompido).

Essas instruções são privilegiadas e só podem ser executadas no ring 0. Veja o que acontece se tentarmos usá-las no userspace:

#include <stdio.h>

void main(void)
{
  __asm__ ("cli");
  puts("Será que chega aqui?");
  __asm__ ("sti");
}

Compilando, linkando e executando, temos:

$ gcc -o test test.c
$ ./test
Segmentation fault

A mesma coisa ocorre ao tentar usar as instruções OUT e IN que, embora não sejam instruções privilegiadas, elas dependem de um mapa de permissão de I/O que é fornecido pelo sistema operacional na estrutura de uma task

Anúncios