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
Can anyone at least tell me what does this error mean in general:
What can go wrong to get this error? What should it mean?
Looks like an ARM error
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?
You wrote .
Maybe this was simply typed in in a quick an dirty way (as opposed to cut&paste), which i deduced from the typo
ctl_bitsvs.ctlbits. But a quickgrep 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, likeoutb %al, $0x92in 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
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):
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?
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
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
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
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.
Yes that new address worked. It was an error in manual.
Thank you.