UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

AR# 38389

12.3 EDK - Interrupts cause multiple accesses to peripheral, corrupting data on PowerPC 440 designs

Description


On a PowerPC 440 system, two accesses can occur to a peripheral location when an interrupt occurs during the first access. This can cause failures when the access is to a location that can only be read or written once for a particular transaction, such as peripheral FIFO location or status register.

What causes this behavior, and how do I avoid it?

Solution

All memory locations that can only be accessed once for a particular value must be part of a Guarded address range in the TLB; see page 141 of the ppc440x5_um.pdf file:
5.6.4 Guarded (G)

The guarded storage attribute is provided to control "speculative" access to "non-well-behaved" memory locations.
Storage is said to be "well-behaved" if the corresponding real storage exists and is not defective, and if the effects of a single access to it are indistinguishable from the effects of multiple identical accesses to it. As such, data and instructions can be fetched out-of-order from well-behaved storage without causing undesired side effects.

In general, storage that is not well-behaved should be marked as guarded. Because such storage may represent a control register on an I/O device or may include locations that do not exist, an out-of-order access to such storage may cause an I/O device to perform unintended operations or may result in a Machine Check exception. For example, if the input buffer of a serial I/O device is memory-mapped, then an out-of-order or speculative access to that location could result in the loss of an item of data from the input buffer, if the
instruction execution is interrupted and later re-attempted.

Work-around:


Set the Guarded bit for all TLB entries that cover I/O peripheral ranges that cannot tolerate multiple accesses. For example, for setting the I/O ranges from 0x8000000-0x9FFFFFFF, use the following code:

#include "xtlb_l.h"

/* Initialize peripherals as guarded */
{
unsigned short page;
int attrib;
int ts; /* Translation Space */

for (ts=0;ts<=1;ts++){

/* 0x8000_0000 to 0x8FFF_FFFF */
page = XTlb_FindPage(0x80000000, 0x0, ts);
attrib = XTlb_GetStorAttribAccessCtrl(page);
XTlb_SetStorAttribAccessCtrl(page, ((short) attrib) | ( 1 << 8 ));

/* 0x9000_0000 to 0x9FFF_FFFF */
page = XTlb_FindPage(0x90000000, 0x0, ts);
attrib = XTlb_GetStorAttribAccessCtrl(page);
XTlb_SetStorAttribAccessCtrl(page, ((short) attrib) | ( 1 << 8 ));
}
}


AR# 38389
Date Created 09/30/2010
Last Updated 12/20/2010
Status Active
Type General Article
Tools
  • EDK - 10.1 sp2
  • EDK - 10.1
  • EDK - 10.1 sp1
  • More
  • EDK - 10.1 sp3
  • EDK - 11.1
  • EDK - 11.2
  • EDK - 11.3
  • EDK - 11.4
  • EDK - 11.5
  • EDK - 12.1
  • EDK - 12.2
  • EDK - 12.3
  • Less
IP
  • PowerPC 440