Operating System-Class 13-March 9th

handout: Slides on Interrupts

 

hw2 questions: hw2 is extended to Fri. night.

lock.h describes a locking API. The basic operations needed are:

·         create a lock

·         lock a certain lock

·         unlock a certain lock

·         destroy a lock

 

Here a “lock” is a mutex. In Xinu, we can create a mutex from a semaphore with semid = screate(1). In UNIX*, we need (from semex.c)

sem_t *semlock;   /* and then shared memory for the pointed to sem_t struct */

sem_init(semlock, 1, 1)   

 

The challenge is to provide a portable API, i.e., same API for Xinu and UNIX*. That means that you need to come up with a “lock id” that hides enough info that it can hold an int semid for Xinu or a sem_t pointer for UNIX*. It can be a struct.

 

We can refine the idea of the API

·         create a lock, returning a portable lockid

·         lock a certain lock, specified by the lockid

·         unlock a certain lock, specified by the lockid

·         destroy a lock, specified by the lockid

 

Back to Interrupts: example of receiver interrupt

 

1. char arrives in serial port

  -- DR bit = 1 in status reg

  -- int signal (if int’s are available in dev)

2. signal comes to PIC may wait here(or mesh off)

     eventually PIC signals CPU

3. CPU executes its “interrupt cycle” between instructions

·   interrupt cycle

o cause change to kernel mode of CPU

o execution of the interrupt handler(OS code)

·         interrupt handler: we write code to acknowledge the PIC and the interrupting device

·         In this case, the int handler sends EOI to PIC and reads the receiver data register.

·         EOI: outb of 0x20 to port 0x20

 

PIC allows us to “mask” an IRQ# via port21.

Ex. Mask off timer(IRQ=0) then its int’s never get through the PIC.

 

So, to get ints to happen:            

1. enable ints in device using outb to appropriate port

                                                2. make sure its IRQ is not masked by PIC

                                                3. make sure CPU has IF=1 (sti instruction if needed)

 

The interrupt cycle in the CPU

The CPU composes an instruction “int $nn” using the nn interrupt vector number, and jams it into its instruction pipeline.  That helps us understand how it can keep track of behavior logically before and after the interrupt, even though it is running a pipeline of instructions.  See Slide 10 for details.

 

The interrupt cycle (but not the system call exception cycle that is so similar) sets IF=0 in EFLAGS, as well as making the CPU run in kernel mode.  This just means that interrupt handlers (always in the kernel) start off running with interrupts off, to ensure they have complete control of the system. 

 

Our simple interrupt handlers leave IF=0 for their whole execution, and depend on the final IRET instruction to restore the old EFLAGS, which must have IF=1.  The IRET also restores the old EIP and CS, to resume the interrupted execution wherever it was in user mode if it was running in user code at the interrupt, or in the kernel code if the interrupt happened there.  (The CS CPU register contains the user mode/kernel mode information.)

 

Look at the slides.   Some notes—

 

Slide 6  “CPU Interrupt Handling”  CPU checks for interrupts between instructions. 

 

pic_end_int(), pic_enable_irq(int irqn), pic_disable_irq(int irqn) are functions implemented in the SAPC library, in directory $pclibsrc.  They are special to UMB’s SAPC environment, although historically based on Linux sources.  The code could be ported to a Windows environment, but could not run there because user code is not allowed to interact directly with hardware (in Windows or UNIX.)  It needs a kernel-like environment to run in, running in kernel mode on the CPU.  The SAPC/Tutor setup provides this kernel-like environment.  (You could run Tutor off a floppy on your home PC, but it’s not easy to set up mtip for downloading to go with it.)

 

Slides 15-18: The UART is two devices in one package: receiver + transmitter.  They share one IRQ line, however, so have only one interrupt handler (that is, one for COM1, another one for COM2.)   These slides only cover receiver interrupts.

 

Note that COM1 and COM2 are already in active use (or ready for it) when we start using them in a program on the SAPC.  COM2 is the console line for ordinary “mtip” sessions, so the Tutor prompt is output on COM2 and our “go 100100” is input on that line.  COM1 is normally used for the remote gdb protocol.  Both these activities use only programmed i/o, i.e., no interrupts.