CS61C Lab 14

Interrupt Driven I/O

Background

Purpose

In this lab, you will supply code for a simplified interrupt-driven output facility.

Exercises

Setup

Copy the contents of ~cs61c/assignments/lab/14 to a suitable location in your home directory.

$ mkdir ~/lab
$ gcp -R ~cs61c/assignments/lab/14/ ~/lab

Start spim as follows:

$ spimsal -memio -quiet

Exercise 0

Thoroughly look through the code in interrupts.s before you start. It is critical that you understand this code before proceeding. The first thing in the file is the usual __start routine. This routine is just an infinite loop that prints out a string of text. The interesting part of this lab is how the print routine works. All it does is transfer characters from the input string that was passed from the caller to the output buffer as long as there is space in the output buffer. If there is no space, the routine simply waits until space appears. This works because an interrupt will occur when the terminal's ready bit goes high and the interrupt service routine will clear space in the output buffer. The interrupt service routine is what you need to write. Programming interrupt service routines is more challenging then programming typical user programs. One reason for this is that the code is not executed in sequence; it is executed based on events. For some pointers on programming interrupt service routines, see the Pointers section below.

Exercise 1

What could happen if the interrupt service routine didn't disable terminal interrupts before returning to the routine that we interrupted?

Exercise 2

Write the code that begins at the notEmpty label of the interrupt service routine.

Pointers

The sequence of events for a system that uses interrupts is different than one that doesn't. Consider the __start routine. It does not know how the print routine works. All it knows is that when the print routine returns, the contents of the string will have been printed. This is the model that we are used to. Now consider the print routine. It knows that when the terminal is ready to take more characters it will interrupt. Therefore, all it has to do is make sure that it does not overflow the output buffer. Note that several complications can arise in this situation that we are not used to dealing with. For example, what would happen if the print routine gets interrupted after it writes a character to the output buffer but BEFORE it updates the nextIn pointer?

Before running spim or xspim, run the following command so the terminal's I/O isn't buffered:

$ stty min 1

Don't forget to run spim with the -memio and -quiet flags. Remember, the -quiet option tells spim not to call the trap handler when an exception occurs. This is critical because YOU are supposed to be handling exceptions. However, while you are writing your code, you may get some nasty bugs that crash spim. Often, these are excetions that you are causing and not handling. For example, if you try to write a word to an unaligned address in spim and the trap handler is disabled, you will probably get a bus error. So, if you get a bus error or a seg fault while running spim, try running it without the -quiet option and you will probably discover the problem. Remember to turn the -quiet option back on after you debug the problem.