|TAMS / Java / Hades / applets: contents | previous | next
adders and arithm...
LFSR and selftest
I/O and displays
CMOS circuits (sw...
Mips R3000 cosimu...
Mips fast Sieve
Mips - game ...
Mips prime n...
Intel MCS4 (i4004)
image processing ...
[Sch04] RALU, Min...
|TinyMips interrupts demo
This applet demonstrates the concepts of interrupt handling
on the MIPS (R3000) series.
The hardware structure used for this applet consists of the processor,
some glue logic, and a single RAM component that stores
both the program and the data generated during program execution.
A few switches allow you to interactively generate interrupts
via the five interrupt-input pins INT0..INT4 provided by the processor.
The counter-compare interrupt (INT5) is demonstrated in the
Exceptions and Interrupts on the MIPS architecture
Basic interrupt service routineBy software convention, registers k0 and k1 (r26 and r27) are reserved for kernel and supervisor software. Whenever the hardware detects an external interXXXXX the corresponding bits are set in the CAUSE register of the system coprocessor (coprocessor 0). Unlike several other microprocessors, the MIPS architecture does not include the so-called vectored interrupts, Instead, the interrupt handler routine will usually check the ExcCode bit field in the CAUSE register and then dispatch to the corresponding subroutine. Due to a clever organization of the ExcCode bit field, this requires only very few machine instructions. Assuming that the memory locations pointed to by interrupt_table are initialized with the start addresses of the interrupt handler routines for the different software and hardware interrupts, the following code is sufficient to decode the exception cause and jump to the corresponding subroutine. Here, we assume that registers t1 and t2 are available for the exception handler:
mfc0 t1, C0_CAUSE nop and t2, t1, 0x3f lw t2, interrupt_table(t2) nop jr t2 ...
Naturally, most exception routines will require more than just two registers (k0, k1). This means that the exception routine must first save the contents of the registers to a special reserved location in memory, and later restore those register contents before returning from the exception handler. A separate exception handler stack is required when nested exceptions are to be used, or when exception handler routines are allowed to call libary subroutines. In this demo, we reserve and use the memory region in the range of
0x.XXXX.YYYY - 0x.XXXX.ZZZZfor the exception handler subroutines. The following code, taken from Dominic&nbps;Sweetman: See Mips Run, is the quintessential MIPS exception handler routine. It simply increments a counter value stored in main memory each time an exception is generated:
.set noreorder .set noat xcptgen: la k0, xcptcount # get address of counter lw k1, 0(k0) # load counter value nop # load delay addu k1, 1 # increment counter sw k1, 0(k0) # store new value mfc0 k0, C0_EPC # get EPC nop # load delay (mfc0 slow) j k0 # return to program rfe # restore from exception # in branch delay slot
The program uses the same idea, but manages a set of eight counters for each of the different exceptions. The base address of those counters is set to 0x.XXXX.ZZZZ. The main program first initializes those counters to zero, then enters a main loop that just incremements another counter value.
You can now click the input switches to generate interrupts. A rising-edge on any of the interrupt inputs of the TinyMipsCop0 processor will set the corresponding interrupt bit in the status register, and the interrupt will be handled as soon as possible. The interrupt handler will first disable further interrupts, then clear the corresponding interrupt pending bit, increment the corresponding counter, re-enable interrupts, and then re-enter the main program.
Wait until the applet is loaded. You can now open the memory-editor (via popup > edit) The memory editor highlights the last read operation in green color, and the last write operation in cyan color, which allows you to easily watch the program execution. Note that the address bus of the standard RAM component is connected to a subset of the MIPS address bus, namely RAM_ADDR[15:0] = MIPS_ADDR[17:2]. Therefore, MIPS addresses or pointer values have to be divided by 4 to get the actual physical address inside the RAM. For example, the MIPS pointer value 0x00000200 used as the start address of the sieve array corresponds to the RAM address 0x00000080.
If you want to change the simulation speed, just select 'edit' on the clock-generator component, then edit the value of the clock-generator 'period' property, and select 'apply' (and 'ok' to close the clock-generator config dialog).
Similarly, open the TinyMips user-interface window (via popup > edit) to watch the register contents during the program execution.
The binary program running on the processor was compiled and linked with the GNU gcc (184.108.40.206) and binutils cross-compiler toolchain on a Linux x86 host, with the final ELF loading and relocation done via the Hades Elf2rom tool. See
|Print version | Run this demo in the Hades editor (via Java WebStart)
|Usage | FAQ | About | License | Feedback | Tutorial (PDF) | Referenzkarte (PDF, in German)