
PID No. 18414B
2 of 3
Serializing Instruction
Using a serializing instruction is generally an
adequate work-around when the mismatch between
peripheral and processor is on the order of several
cycles.
A serializing instruction requires that all other
instructions in the pipe complete before it executes.
As explained earlier, adding a serializing instruction
between a LOAD/STORE and an IRET forces a
LOAD before the IRET, maximizing the amount of
time the peripheral has to clear the interrupt before
the processor executes the interrupt return sequence.
In the 29K Family of microprocessors and
microcontrollers, the serializing instructions are as
follows. (Note that for 29K Family microcontrollers,
any access to an internal peripheral control or status
register is also a serializing instruction.)
Move to Special Register (MTSR)
Move to Special Register Immediate (MTSRIM)
Move to Translation Look-aside Buffer (MTTLB)
Interrupt Return (IRET)
Interrupt Return and Invalidate (IRETINV)
Enter Halt Mode (HALT)
When adding a serializing instruction, most users
choose to serialize using the “mtsr gr
xx
, lru”
instruction. If the application does not use MMU, or
all pages are mapped by the TLBs (page misses never
occur), then serialization can be accomplished with
this single instruction. Otherwise, the special register
value must be saved with an MFSR instruction before
serialization occurs with an MTSR instruction.
For example, an interrupt is cleared in an Am85C30
peripheral device by writing a zero to the SCC
control register for that port. Adding the serializing
instruction would look like the following:
msg_scc8530_tx_intr:
; reset tx interrupt.
const it1, SCC8530_CHA_CONTROL
consth it1, SCC8530_CHA_CONTROL
const it0, 0
store 0, 1, it0, it1
mfsr it0, lru
mtsr lru, it0
.
{rest of handler}
.
iret
Adding the serializing instruction simply ensures that
the interrupt-clearing LOAD or STORE actually
appears on the bus as soon as possible, maximizing
the amount of time the peripheral has to clear the
interrupt before the processor executes the IRET. The
following sections explain how to guarantee the
peripheral has adequate time to clear the interrupt
before the processor executes the IRET.
Busy Loop
The work-around described above can be enhanced
by following the interrupt-clearing LOAD/STORE
with a STORE/LOAD loop that continues until the
peripheral has had time to process the clearing of the
interrupt.
Based on the same example from the previous section
and using the busy loop approach, an interrupt
handler that resets the transmit interrupt would look
like the following
msg_scc8530_tx_intr:
; reset tx interrupt.
const it1, SCC8530_CHA_CONTROL
consth it1, SCC8530_CHA_CONTROL
const it0, 0
store 0, 1, it0, it1
bsy_loop:
load 0, 1, it1, it0
cpeq it0, it0, 0
jmpf it0, bsy_loop
nop
.
.
{rest of handler}
.
iret
Although this is a guaranteed work-around, remember
that the busy loop can degrade system performance
for some applications. For this reason, it is desirable
to overlap as much of the peripheral’s response time
as possible with the interrupt handling. So, the busy
loop in the above example could be moved after
“{rest of handler}”.
Delay Loop
An alternate way to enhance the work-around is by
adding a delay loop. This requires the developer to
know the exact hardware parameters of the system as
each delay loop is tuned to the specific parameters of
the design under development. The positive tradeoff
for this loss of flexibility is that the delay loop
involves less bus traffic than the busy-loop, which
may be very important in the system. In addition, this
approach minimizes the overhead to the minimum
required.
The delay in the delay loop is determined by:
DELAY = 2 cycles + access_time + periph_time
The first two cycles are required to present the
interrupt-clearing LOAD/STORE to the bus. The
access_time
value is the time in processor cycles that