..
$Header: /home/ff/cs61c/cvsroot/assignments/lab/14.pollingio/index.rst,v 1.6 2005/11/30 23:42:29 cs61c-tc Exp $
============
CS61C Lab 14
============
--------------------
Interrupt Driven I/O
--------------------
Reading
=======
* P&H Chapter A.7. You can find an online copy here_.
.. _here: http://www.cs.wisc.edu/~larus/HP_AppA.pdf
Goal
====
In this lab, you will supply code for a simplified interrupt-driven
output facility.
Exercises
=========
Setup
-----
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)?
Checkoff
~~~~~~~~
.. raw:: html
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``)?
Checkoff
~~~~~~~~
.. raw:: html
Answer to the above question
| |
Exercise 3
----------
Explain the functions of the 3 indicated lines (line 44-46) in ``kernel.s``.
Checkoff
~~~~~~~~
.. raw:: html
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?
Checkoff
~~~~~~~~
.. raw:: html
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
Checkoff
~~~~~~~~
.. raw:: html
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.