* MPC5200b kernel module memory mapping
@ 2006-09-21 0:09 Steven Kaiser
2006-09-21 8:47 ` sudheer
2006-09-21 18:10 ` Markus Klotzbücher
0 siblings, 2 replies; 5+ messages in thread
From: Steven Kaiser @ 2006-09-21 0:09 UTC (permalink / raw)
To: linuxppc-embedded
In a kernel module, I am trying to iomemory map or ioport map a range of
addresses so later I can talk directly to custom external hardware. I have
tried to follow the advice of Rubini chapter 8. I think I am setting it up
correctly, but at the precise moment I try to write anything within my
range, the kernel crashes badly. My board is a Lite5200b, using a 2.4.25
kernel.
#define MALab_DEVICE_NAME "MALab"
#define MALab_MM_START 0x60000000U
#define MALab_MM_END 0x6000ffffU
#define MALab_MM_SIZE 0x00010000U
#define MPC5xxx_MM_CS2_START (MPC5xxx_MBAR + 0x0014)
#define MPC5xxx_MM_CS2_STOP (MPC5xxx_MBAR + 0x0018)
#define MPC5xxx_MM_IPBI (MPC5xxx_MBAR + 0x0054)
void *ioaddr = NULL;
// start 'em up
int init_module(void) {
register_chrdev(...
// reserve a page of memory for our hardware /proc/iomem
if ( check_region(MALab_MM_START,MALab_MM_SIZE) ) {
printk (KERN_ALERT "LED init_module: memory already in
use\n");
return -EBUSY;
}
request_region(MALab_MM_START,MALab_MM_SIZE,MALab_DEVICE_NAME);
// enable LocalBus Chip Select CS2 to hit on our address range
*(volatile u32 *)MPC5xxx_MM_IPBI &= ~0x00040000;
*(volatile u16 *)(MPC5xxx_MM_CS2_START + 2) = MALab_MM_START >> 16;
*(volatile u16 *)(MPC5xxx_MM_CS2_STOP + 2) = MALab_MM_END >> 16;
*(volatile u32 *)MPC5xxx_MM_IPBI |= 0x00040000;
// map our physical address into kernal virtual address space
// do I need this call?
ioaddr = ioremap(MALab_MM_START,MALab_MM_SIZE);
return 0;
}
Later (in a ioctrl routine), I will try and write something to the first
location in my address range. I tried these three ways:
*(volatile u16 *)MALab_MM_START = 0x5555;
outw(0x5555,MALab_MM_START);
outw(0x5555,ioaddr);
Any and all of the these calls crash the kernel so horrendously I have to
reboot. Sometimes I have to delete and mknod a new /dev entry.
I have tried the io memory map technique instead of the above io port map
technique, using request_mem_region(), with the same crashing results upon
any writew() call or direct variants. I tried things without the ioremap()
call-- I get a segmentation fault in these cases.
The request_region() or request_mem_region() seems to work ok. I can cat
/proc/iomem or /proc/ioports and see my range in there. I am pretty sure I
am setting up the LocalBus chip select registers ok.
Yet obviously I am doing something profoundly stupid. Is my error obvious?
Can someone enlighten me in my darkness?
Steven Kaiser
Chemistry Electronics Facility
University of California, Irvine
2347 Natural Sciences 2
Irvine, CA 92697-2025
(949)824-7520
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: MPC5200b kernel module memory mapping
2006-09-21 0:09 MPC5200b kernel module memory mapping Steven Kaiser
@ 2006-09-21 8:47 ` sudheer
2006-09-21 18:10 ` Markus Klotzbücher
1 sibling, 0 replies; 5+ messages in thread
From: sudheer @ 2006-09-21 8:47 UTC (permalink / raw)
To: Steven Kaiser; +Cc: linuxppc-embedded
Hi Stevenson Kaiser,
Steven Kaiser wrote:
> #define MPC5xxx_MM_IPBI (MPC5xxx_MBAR + 0x0054)
>
> void *ioaddr = NULL;
>
>
> // map our physical address into kernal virtual address space
> // do I need this call?
> ioaddr = ioremap(MALab_MM_START,MALab_MM_SIZE);
>
>
Try typecasting. ioaddr = (u16 *)ioremap (start, size );
Regards
Sudheer
> return 0;
> }
>
> Later (in a ioctrl routine), I will try and write something to the first
> location in my address range. I tried these three ways:
>
> *(volatile u16 *)MALab_MM_START = 0x5555;
> outw(0x5555,MALab_MM_START);
> outw(0x5555,ioaddr);
>
> Any and all of the these calls crash the kernel so horrendously I have to
> reboot. Sometimes I have to delete and mknod a new /dev entry.
>
> I have tried the io memory map technique instead of the above io port map
> technique, using request_mem_region(), with the same crashing results upon
> any writew() call or direct variants. I tried things without the ioremap()
> call-- I get a segmentation fault in these cases.
>
> The request_region() or request_mem_region() seems to work ok. I can cat
> /proc/iomem or /proc/ioports and see my range in there. I am pretty sure I
> am setting up the LocalBus chip select registers ok.
>
> Yet obviously I am doing something profoundly stupid. Is my error obvious?
> Can someone enlighten me in my darkness?
>
> Steven Kaiser
> Chemistry Electronics Facility
> University of California, Irvine
> 2347 Natural Sciences 2
> Irvine, CA 92697-2025
> (949)824-7520
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: MPC5200b kernel module memory mapping
2006-09-21 0:09 MPC5200b kernel module memory mapping Steven Kaiser
2006-09-21 8:47 ` sudheer
@ 2006-09-21 18:10 ` Markus Klotzbücher
2006-09-23 20:46 ` Steven Kaiser
2006-09-23 20:55 ` Steven Kaiser
1 sibling, 2 replies; 5+ messages in thread
From: Markus Klotzbücher @ 2006-09-21 18:10 UTC (permalink / raw)
To: Steven Kaiser; +Cc: linuxppc-embedded
Hi Steven,
"Steven Kaiser" <skaiser.uci@gmail.com> writes:
> In a kernel module, I am trying to iomemory map or ioport map a range of
> addresses so later I can talk directly to custom external hardware. I have
> tried to follow the advice of Rubini chapter 8. I think I am setting it up
> correctly, but at the precise moment I try to write anything within my
> range, the kernel crashes badly. My board is a Lite5200b, using a 2.4.25
> kernel.
...
> // enable LocalBus Chip Select CS2 to hit on our address range
> *(volatile u32 *)MPC5xxx_MM_IPBI &= ~0x00040000;
> *(volatile u16 *)(MPC5xxx_MM_CS2_START + 2) = MALab_MM_START >> 16;
> *(volatile u16 *)(MPC5xxx_MM_CS2_STOP + 2) = MALab_MM_END >> 16;
> *(volatile u32 *)MPC5xxx_MM_IPBI |= 0x00040000;
>
> // map our physical address into kernal virtual address space
> // do I need this call?
> ioaddr = ioremap(MALab_MM_START,MALab_MM_SIZE);
Yes, you do need this call if you want to access physical addresses.
> return 0;
> }
>
> Later (in a ioctrl routine), I will try and write something to the first
> location in my address range. I tried these three ways:
>
> *(volatile u16 *)MALab_MM_START = 0x5555;
> outw(0x5555,MALab_MM_START);
> outw(0x5555,ioaddr);
>
> Any and all of the these calls crash the kernel so horrendously I have to
> reboot. Sometimes I have to delete and mknod a new /dev entry.
>
> I have tried the io memory map technique instead of the above io port map
> technique, using request_mem_region(), with the same crashing results upon
> any writew() call or direct variants. I tried things without the ioremap()
> call-- I get a segmentation fault in these cases.
>
> The request_region() or request_mem_region() seems to work ok. I can cat
> /proc/iomem or /proc/ioports and see my range in there. I am pretty
This doesn't really tell you anything, it's mere housekeeping.
> sure I am setting up the LocalBus chip select registers ok.
I would guess this is not the case. What kind of device is this?
Regards
Markus
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: MPC5200b kernel module memory mapping
2006-09-21 18:10 ` Markus Klotzbücher
@ 2006-09-23 20:46 ` Steven Kaiser
2006-09-23 20:55 ` Steven Kaiser
1 sibling, 0 replies; 5+ messages in thread
From: Steven Kaiser @ 2006-09-23 20:46 UTC (permalink / raw)
To: 'Markus Klotzbücher'; +Cc: linuxppc-embedded
Markus:
> > sure I am setting up the LocalBus chip select registers ok.
>
> I would guess this is not the case. What kind of device is this?
It is a Freescale MPC5200b:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPC5200B
You are correct. I was so concerned about the linux driver stuff (
request_region(), ioremap(), etc ), that I was locked into endless studies
on that and see now I clearly overlooked some simple chip setting up. Doh!
Thanks for reorienting my focus--
int init_module(void) { ...
// reserve a page of memory for our hardware /proc/iomem
if ( check_region(MALab_MM_START,MALab_MM_SIZE) ) {
printk (KERN_ALERT "LED init_module: memory already in
use\n");
return -EBUSY;
}
request_region(MALab_MM_START,MALab_MM_SIZE,LED_DEVICE_NAME);
// enable LocalBus chip select CS2 to hit on our address range
*(volatile u32 *)MPC5xxx_MM_IPBI &= ~0x00040000;
*(volatile u16 *)(MPC5xxx_MM_CS2_START + 2) = MALab_MM_START >> 16;
*(volatile u16 *)(MPC5xxx_MM_CS2_STOP + 2) = MALab_MM_END >> 16;
*(volatile u32 *)MPC5xxx_MM_IPBI |= 0x00040000;
// LocalBus Chip Select 2,3 Configuration Register
*(volatile u32 *)(MPC5xxx_MBAR + 0x0308) = 0x03031110;
*(volatile u32 *)(MPC5xxx_MBAR + 0x030c) = 0x03031110;
// LocalBus Chip Select Control Register
*(volatile u32 *)(MPC5xxx_MBAR + 0x0318) |= 0x01000000;
// map our physical address into kernal virtual address space
ioaddr = ioremap(MALab_MM_START,MALab_MM_SIZE);
printk(KERN_ALERT "ioaddr: 0x%08x\n", (u32)ioaddr);
and later, any of these calls work:
^ permalink raw reply [flat|nested] 5+ messages in thread
* RE: MPC5200b kernel module memory mapping
2006-09-21 18:10 ` Markus Klotzbücher
2006-09-23 20:46 ` Steven Kaiser
@ 2006-09-23 20:55 ` Steven Kaiser
1 sibling, 0 replies; 5+ messages in thread
From: Steven Kaiser @ 2006-09-23 20:55 UTC (permalink / raw)
To: 'Markus Klotzbücher'; +Cc: linuxppc-embedded
Markus:
> > sure I am setting up the LocalBus chip select registers ok.
>
> I would guess this is not the case. What kind of device is this?
You are correct. I was so concerned about the linux driver stuff (
request_region(), ioremap(), etc ), that I was locked into endless studies
on that and see now I clearly overlooked some simple chip setting up. Doh!
Thanks for reorienting my focus--
My chip is a Freescale MPC5200b:
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MPC5200B
So here's what I've doing that seems to work, as verified by an
oscilloscope:
// 64k I/O Port Space: 0x60000000 - 0x60001000 -> 0x60000000 - 0x60001000
#define MPC5xxx_MM_CS2_START (MPC5xxx_MBAR + 0x0014)
#define MPC5xxx_MM_CS2_STOP (MPC5xxx_MBAR + 0x0018)
#define MPC5xxx_MM_IPBI (MPC5xxx_MBAR + 0x0054)
#define MALab_MM_START 0x60000000U
#define MALab_MM_END 0x6000ffffU
#define MALab_MM_SIZE 0x00010000U
void *ioaddr = NULL;
int init_module(void) { ...
// reserve a page of memory for our hardware /proc/iomem
if ( check_region(MALab_MM_START,MALab_MM_SIZE) ) {
printk (KERN_ALERT "LED init_module: memory already in
use\n");
return -EBUSY;
}
request_region(MALab_MM_START,MALab_MM_SIZE,LED_DEVICE_NAME);
// enable LocalBus chip select CS2 to hit on our address range
*(volatile u32 *)MPC5xxx_MM_IPBI &= ~0x00040000;
*(volatile u16 *)(MPC5xxx_MM_CS2_START + 2) = MALab_MM_START >> 16;
*(volatile u16 *)(MPC5xxx_MM_CS2_STOP + 2) = MALab_MM_END >> 16;
*(volatile u32 *)MPC5xxx_MM_IPBI |= 0x00040000;
// LocalBus Chip Select 2 Configuration Register
*(volatile u32 *)(MPC5xxx_MBAR + 0x0308) = 0x03031110;
// LocalBus Chip Select Control Register
*(volatile u32 *)(MPC5xxx_MBAR + 0x0318) |= 0x01000000;
// map our physical address into kernal virtual address space
ioaddr = ioremap(MALab_MM_START,MALab_MM_SIZE);
printk(KERN_ALERT "ioaddr: 0x%08x\n", (u32)ioaddr);
then later, any of these calls work (even in interrupt routines it appears):
u32 buf[10];
*(volatile u16 *)ioaddr = 0x5555;
outw(0x5555,ioaddr);
outsw(ioaddr,buf,10);
I guess this is simple stuff for most everybody here.
Steve
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-09-23 20:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-21 0:09 MPC5200b kernel module memory mapping Steven Kaiser
2006-09-21 8:47 ` sudheer
2006-09-21 18:10 ` Markus Klotzbücher
2006-09-23 20:46 ` Steven Kaiser
2006-09-23 20:55 ` Steven Kaiser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).