# Periféricos e Interrupções
Um periférico é um conjunto de registos, periféricos diferentes têm registos diferentes. Os registos do periférico são diferentes dos registos do processador.
Os registos dos periféricos são mapeados numa gama de endereços específica. Para aceder aos dados na memória utilizamos as instruções convencionais: lw e sw, mas para realizar a leitura/escrita de dados no periféricos existem instruções específicas:
iolw Xn, xpto -> leitura do registo com o endereço xpto
iosw Xn, xpto -> escrita no registo
Saber para o teste
Port-Mapped I/O: Barramentos independentes de acesso à memória e aos periféricos
Memory-Mapped I/O: Barramento único para acesso à memória e aos periféricos.
# Interrupções e Exceções
Interrupções - Evento desencadeado por uma entidade exterior ao processador.
Ex: O utilizador mexeu no rato ou inseriu uma pen USB
Exceções - Evento gerado em consequência da execução de uma instrução.
Ex: Divisão por 0 ou a execução de uma instrução "ilegal"
# Para resolver a Interrupção ou Exceção:
- Termina a execução atual
- Chama a sub-rotina que atende a interrupção
- Retorna ao ponto inicial executando a instrução seguinte
Esta sub-rotina não deve:
- Alterar qualquer registo do processador
- Alterar a stack
Mas deve:
- Guardar o endereço de retorno (No RISC-V, SEPC)
- O PC passa a apontar para a 1ª instrução da rotina do tratamento de interrupções
- Salvaguardar na pilha o registo de todos os endereços alterados pela rotina de interrupções
- Consultar o registo SCAUSE que nos indica a causa da interrupção
- Realizar o processamento relativo à rotina de interrupções
- Repor o contexto
- Retornar ao programa original (SRET: PC <- SEPC)
# Control and Status Registers (CSR's)
SIE (Supervisor Interrupt-Enable Register) - Permite ativar ou desativar todas as interrupções/exceções globais ou ativar/desativar apenas de um periférico específico
SIP (Supervisor Interrupt-Pending Register) - Permite saber se existe uma interrupção/exceção por atender
SSTATUS (Supervisor Status Register) - Contém o GIE (Global Interrupt Enable) e o SPIE (Global Prior Interrupt Enable). O SPIE contém o valor lógico do bit GIE antes de atendermos a interrupção.
STVEC (Supervisor Trap Vector Base Register) - Guarda o endereço da 1ª instrução da rotina de tratamento
SEPC (Supervisor Exception PC) - Guarda o endereço de retorno
Exemplo:
// Indique o número e valor de todos os registos escritos
// pela execução do troço de código indicado:
li x10, 0x000F 0000
csrrs x0, 0x104, x10
Indo ao Reference Card, podemos tirar que csrrs corresponde a um CSR Read and Set da forma csrrs xd, csr, xa
. Assim, o ID do CSR corresponde a 0x104 o que corresponde a um SIE.
Como, pela primeira imagem, temos que CSR[csr] ← CSR[csr] | xa
e o ID do CSR corresponde a um SIE, substituindo temos:
SIE = SIE | x10 ⇔ SIE = 000F FFFFh
Olhando para a imagem do enunciado, temos que SIP = 0004 0000h e que SSTATUS = 0000 0002h = (...) 0010 , este bit equivale ao GIE GIE = 1.
Assim, podemos concluir que há uma interrupção pendente associada ao periférico/excepção 18 (isto porque se convertermos o SIP para binário temos 0100 0000 0000 0000 0000, ou seja, o 18º bit está a 1) e, por isso, chama-se a rotina de interrupções.
- O SEPC correponde ao endereço da instrução a seguir ao csrrs, como o PC se encontrava em 0000 014Ch, somando 2 instruções ficamos com SEPC = 158h.
- O PC aponta para a 1ª instrução da rotina de interrupções que está guardado no STVEC: PC STVEC PC = 000A 0000h (pela imagem do enunciado).
- O SPIE corresponde ao valor lógico de GIE antes de atender a interrupção, SPIE = 1
- Pelo Reference Card, podemos concluir que o 5º e o 1º bits do SSTATUS correpondem ao SPIE e ao GIE, respectivamente. Assim, temos que SPIE = (...)0010 0000 = 0000 0020h.