CS61C Lab 14

Interrupt Driven I/O

End of Semester Survey -- Required for Checkoff
Please take the time to fill in this survey honestly and completely. Your answers are completely anonymous. You will be asked for your login, but this is only to record that you have done this part of the lab and may be checked off for it. Your login will not be associated with your answers to the other survey questions.



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



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

$ mkdir ~/lab
$ cp -R ~cs61c/labs/14/ ~/lab

Exercise 0

Read Chapter A.7 from P&H. It will greatly assist you in understanding the code for this lab.

Thoroughly look through the code before you start. It is critical that you understand this code before proceeding.

There are 2 assembly files for thie lab: exceptions.s is an exception handler, and kernel.s is the main application. We will implement the entire application in kernel mode (.ktext rather than .text) to simplify userland/kernel interactions.

The first thing in the application file is the usual main() procedure. 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 than 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 section Writing Interrupt Handler below.

Exercise 1

Based on the code we have supplied for this lab, is it possible to have nested interrupt (interrupted during an interrupt service routine)?


Answer to the above question  

Exercise 2

What could happen if the interrupt service routine didn't disable terminal interrupts before returning to the routine that we interrupted (line 29, exceptions.s)?


Answer to the above question  

Exercise 3

Explain the functions of the 3 indicated lines (line 44-46) in kernel.s.


Answer to the above question  

Exercise 4

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?


Explain why the circular buffer eliminates race condition between interrupt handler and the main code.  

Exercise 5

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

To run your code, you will need to execute xspim as follows:

$ xspim -exception_file exceptions.s -mapped_io -file kernel.s


Run and show your code to your TA.  

Writing Interrupt Handler

The sequence of events for a system that uses interrupts is different than one that doesn't. Consider the main 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, such as the question in Exercise 4 above.

Since you are implementing your own exception handler, you may get some nasty bugs that crash spim. Often, these are caused by exceptions that you are accidently triggering but are 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, this is likely the cause.

Beyond This Lab

If you have time, try to modify kernel.s such that interrupts for both input and output are enabled. Then, implement an interrupt handler that handles interrupts from your keyboard, and display the key stroke to the screen using the knowledge you have learned in this lab.