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