XScale (ARM-PXA255) -> "imprecise external abort"

Submitted by dzek
on May 25, 2005 - 8:16am

When I try to access TTL outputs which are on physical address 0x19800000, I get kernel oops: "imprecise external abort".
I am using kernel v2.6.9 on ARM platform (XScale, PXA255) on ConXS board and the code with which I am accessing this memory is:


#define CS_IO_OUT 0x19800000
ctl_bits = NULL;
if (!request_mem_region(CS_IO_OUT, 2, "Control bits on TTL - J2"))
{
printk(KERN_ERR "Unable to reserve TTL control bits region\n");
return -ENODEV;
}
else
{
ctl_bits = ioremap(CS_IO_OUT, 2);
if (!ctl_bits)
{
printk(KERN_ERR "Unable to map region!\n");
return -ENODEV;
}
}
outb(ctlbits,(1<<bit_num));

I tried to google for a useful anwser, but have found nothing.
I can't see what is the problem?

Thank you in advance!
Anton Sodja

Can anyone at least tell me w

dzek
on
May 26, 2005 - 7:29am

Can anyone at least tell me what does this error mean in general:
Unhandled fault: imprecise exteral abort (0x406) at 0x401275ea

What can go wrong to get this error? What should it mean?

Looks like an ARM error

farnz
on
May 26, 2005 - 2:45pm

At first glance (and I've not played with XScale), that looks like an ARM hardware trap. This suggests that either the kernel isn't set up to let you access that address, or that the hardware isn't at the address you think it is (MMUs and the like).

wrong arguments?

strcmp
on
May 26, 2005 - 3:38pm

You wrote outb(ctlbits,(1<<bit_num));.

Maybe this was simply typed in in a quick an dirty way (as opposed to cut&paste), which i deduced from the typo ctl_bits vs. ctlbits. But a quick grep outb arch/arm/*/* tells me you may have reversed the arguments of outb. Try to swap them back... The outb() functions seems to be modeled after the AT&T assembler syntax, like outb %al, $0x92 in the i386 directory.

Btw, i read "imprecise external abort" as "external abort, which was delivered imprecisely", i.e. there is no connection between the instruction causing the abort and the instruction pointer in the error message, because the hardware needed some time to detect the error condition and the cpu executed more code in the mean time. Is this correct?

You are right about arguments

dzek
on
May 27, 2005 - 7:04am

You are right about arguments passed to outb macro, I just added a line at the end, because code is spread across the module:
io.h:#define outb(v,p) __raw_writeb(v,__io(p))
I also tried writeb(), writew(), direcly with pointers; all with no success.

That is all what is written in board's datasheet (except the part with pins description):

3.12 TTL I/O
ConXS offers 8 TTL Inputs and 8 TTL Outputs. The TTL Outputs are accessible by
the connector J1, the TTL Inputs by the connector J2. The output signals (OUTPUT[
0:7]) correspond with dataline signals D[0:7], which are switched by a CPLD.
They will be selected by addressing 0x19800000 (\CS_IO_OUT and \CS_IO_IN).
The Inputs can be read as follows:
read = *(short *) ADR
The Outputs can be written as follows:
*(short *) portadr = value

If I use direcly this address, I get error at virtual pointer 0x19800000. If I do ioremap, then error is already mentioned imprecise external abort.

And what do you mean with ARM hardware trap?
If kernel is configured wrong, in what configuration section should I change it?

because the hardware needed some time to detect the error condition and the cpu executed more code in the mean time. Is this correct?

I don't know. I test it with ioctl function and there is only 'break;' and 'return 0' statement after obtb macro in file_operations.ioctl.

Check the XScale manual

farnz
on
May 27, 2005 - 10:48am

Looking at an ARM manual, an "imprecise external abort" occurs when the chip attempts an external read or write, continues executing from the pipeline (as there are no dependencies), then fails to complete the read or write. As it's lost track of which instruction started the access, it's imprecise. The external abort refers to the external device (not part of the CPU core) refusing to complete the transaction.

Best guess is that you've got the address wrong. If not, the hardware is doing something funny, and you really need to point us to complete manuals for the board you're using.

still not working

dzek
on
May 30, 2005 - 2:18am

This morning I tried all wariants of out{b|w} and write{b|w} variants again. With no success.
This code should work, but it doesn't:

#define CS_IO_OUT 0x19800000
/* defined as static variable in module */
void *ctl_bits;


/* that is done in function passed to 'module_init()' */
ctl_bits = NULL;
if (!request_mem_region(CS_IO_OUT, 2, "Control bits on TTL - J2"))
{
printk(KERN_ERR "Unable to reserve TTL control bits region\n");
return -ENODEV;
}
else
{
ctl_bits = ioremap(CS_IO_OUT, 2);
if (!ctl_bits)
{
printk(KERN_ERR "Unable to map region!\n");
return -ENODEV;
}
}

/* and that is code that writes to that address */
int ad_conv_ioctl(struct inode *inode, struct file *filep,
unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
/* ... */
case AD_CONV_TEST:
outb(1<<arg,ctl_bits);
break;
/* ... */
}

All parameters passed to functions are fine (checked with printk).

I am referring to this to manuals (all what is writen about TTL outputs is on page 14):
http://www.keith-koep.com/produkte_ConXS/doc/ConXS_01_1.pdf

So what could be the problem? Defective hardware?

Confusing manual

farnz
on
May 31, 2005 - 11:47am

Page 42 of that manual suggests that you should be writing to CS3 + 0x01800000 (0x0d800000 unless you've resoldered the CS lines). If that doesn't work (in your sample code, change #define CS_IO_OUT 0x19800000 to #define CS_IO_OUT 0x0d800000), you'll need to break out a logic analyser, and see if the bus is driven.

Yes that new address worked.

dzek
on
June 2, 2005 - 4:03am

Yes that new address worked. It was an error in manual.

Thank you.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.