11 Mar 2007 lethal   » (Master)

Notes on SH interrupt/exception dispatch path

Some people are seemingly confused about the semantic changes that have happened for the unified exception dispatch path in the SH-3/4 code, so it's probably worth reiterating what changed, and why you don't want to touch the interrupt exception tables.

Most of the exceptions (especially general exceptions and interrupt exceptions) are immediately bounced through handle_exception once the exception code has been appropriately stashed in r2, with the return path sitting in r3. Traditionally this has included the EXPEVT value in the general exception case, and INTEVT for the interrupt exceptions, which could then be used for calculating the offset in to a flat jump-call table (exception_handling_table). This worked well for general exceptions, but rather less so for interrupt exceptions. In the IRQ case we ended up with many CPU subtypes with very sparse IRQ maps, that would only be interested in selectively enabling do_IRQ() dispatch for a handful of vectors. While this worked fine for a very small number of CPU subtypes, it very quickly got out of hand and turned in to a giant ifdef fiasco that was highly prone to off-by-one vector enabling and other ugly things.

In order to get rid of all of these accursed tables, the exception code read-in and the handle_exception dispatch needed a bit of rework. The regular case is that general exceptions exist first in the vector table, with the interrupt exceptions following afterwards. There are some minor corner cases where there is overlap, but those vectors can be overloaded by the CPUs that need special care.

Enter the interrupt exception marker. With the marker scheme, a simple marker is placed in r2 to signify a do_IRQ() fast-path while deferring the INTEVT read. This is then looked at when figuring out whether to take the r2 value as a jump-call table offset or whether to dispatch directly. There are some additional notes regarding this in the tail end of handle_exception for anyone that's too concerned.

The only pitfall with this scheme is that the vector tables have to be padded out so a fixed length in order to allow setting specific exception handlers that happen to reside far out in the table (as is the case with some of the FPU exceptions). Two new routines have been added for this purpose, set_exception_table_evt() and set_exception_table_vec(). The use of both of these is fairly obvious to anyone looking at the vector tables, so there's no point in reiterating it here.

In practice this hasn't worked out too badly:

4 files changed, 40 insertions(+), 721 deletions(-)

For additional reading, consult arch/sh/kernel/traps.c, arch/sh/kernel/cpu/sh3/entry.S and arch/sh/kernel/cpu/sh[34]/ex.S.

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!