I/O
Ciencias de la Computación III
Diego José Figueroa
Manejo de Input/Output
- Memory Mapped I/O
- Mecanismo que consiste en mapear un periférico a una dirección de memoria.
- Normalmente, se utilizan direcciones altas, permitiendo hacer una escritura/lectura a "memoria", pero que en realidad se hace sobre el dispositivo mapeado.
- Permite agregar dispositivos de forma fácil y simple.
Mouse ficticio
- Mouse de mentiras, con propósito de ejemplo.
- Únicamente tiene 1 botón.
- Se maneja con 2 registros
- Status Register: Indica si sucedió un cambio (click o movimiento)
- Data Register: Indica la magnitud del movimiento, y si se presionó el botón.
Mouse ficticio
Status Register
- LSB indica si hay nuevos datos del mouse (movimiento o click).
- Sólo es 1 cuando hay datos.
- Cuando se lee el Data Register, se regresa a 0.
- El 2do bit, se usa para activar interrupciones.
- Si deseamos provocar una interrupción cada vez que haya movimiento, se coloca en 1.
- De lo contrario, se deja en 0.
Data Register
- El Byte menos significativo almacena el desplazamiento horizontal, un número de 8bits con signo.
- El 2do byte, contiene el desplazamiento vertical, un número de 8bits con signo.
- El 3r byte contiene 1 si se presionó el botón, es 0 de lo contrario.
- El resto de bits están reservados para futuras implementaciones
- Por ejemplo, añadir botones.
¿Cómo lo usamos?
- Podemos verificar el Status Register frecuentemente.
- Cuando éste indique algún cambio:
- Leemos el Data Register.
- Procesamos los datos.
- Regresamos a nuestra labor.
- A esto se le llama Polling.

Analogía del Pastel Sabroso
Implementación
.data
horiz: .integer 0
vert: .integer 0
button: .integer 0
.text
pollMouse:
la $t0 0xffff0010 #mouse stt
pollingLoop:
lw $t1 0($t0)
andi $t1 $t1 0x1
beqz $t1 pollingLoop
Implementación
lw $t1 4($t0) # data reg
sll $t2 $t1 24 # aislamos el 1er byte
sra $t2 $t2 24 # sign extend
la $t3 horiz
lw $t4 0($t3)
add $t4 $t4 $t2
sw $t4 0($t3)
sll $t2 $t1 16 # aislamos el 2do byte sra $t2 $t2 24
la $t3 vert
lw $t4 0($t3)
add $t4 $t4 $t2
sw $t4 0($t3)
Implementación
srl $t2 $t1 16
la $t3 button
sw $t2 0($t3)
jr $31
Polling
- Estamos en un ciclo infinito, preguntando por novedades.
- Cuando hay cambios, cargamos los datos.
- De lo contrario no hacemos nada.
- Ventajas
- Es muy simple.
- Funciona.
- Desventajas
- Pasamos mucho tiempo sin hacer nada.
- Es ineficiente.
Interrupciones
- Llamada a una función, de forma asíncrona, como respuesta a un evento.
- Cuando se dispara una interrupción, una computadora deja lo que está haciendo para atenderla.
- Esto se encarga el manejador de interrupciones.
¿Para qué?
- I/O
- Teclado, mouse, gamepads, network, etc.
- Señales especiales
- Batiseñal
- Problemas en programas
- Errores (división por cero, accesos a memoria inválida, etc.)
- Timer interrupts
- Multitasking
¿Qué tienen en común?
- Eventos que el programa actual no planeó, provocados por algún agente externo
- Usuario
- Red
- Dispositivos externos
- Errores
Una interrupción
- Es una señal especial para el procesador
- Manejada por el coprocesador 0 en MIPS.
- Provoca un jalr a la dirección del Exception Handler.
Interrupciones en MIPS
- Cuando se levanta una interrupción
- Se desactivan otras interrupciones, evitando interrumpir una interrupción.
- Esto significa que la rutina de manejo debe ser muy rápida.
- El manejador de interrupciones se encuentra en 0x80000010.
- De forma que el coprocesador siempre sabe a dónde saltar.
Al entrar al handler
- Se guardan todos los registros a utilizar (incluyendo $at).
- Se examinan todas las posibles fuentes de la interrupción, una vez se identifica la causa ($13), se procede según se necesite:
- Intento de división por 0.
- Lectura completa de HDD.
- Movimiento del mouse.
- Al terminar, se debe restaurar los registros del stack, y luego:
- mfc0 $k0 $14 # dirección de "retorno"
- rfe # habilita interrupciones
- jr $k0
mfc0 $k0 $14
- $14 es un registro del coprocesador, llamado Interrupt Program Counter.
- Contiene una copia del PC al momento de la interrupción.
- Copiamos a $k0 porque es un registro reservado para el kernel.
¿Por qué no usamos $ra?
rfe
- rfe habilita las interrupciones después de la siguiente instrucción.
-
¿Por qué es importante habilitar las interrupciones al terminar el exception handler?
18 - Manejo de I/O
By Diego Figueroa
18 - Manejo de I/O
- 895