DMA in powerpc 405EP

ashok.athukuri - August 27, 2010

Hello All,

I'm looking forward to implement DMA for a memory device (mapped to the powerpc 405EP EBC bus), but I dont know where to start !?. Is it u-boot first or the kernel?

Please suggest me some tutorial links to implement this.

 

 

Regards,

Ashok 

 

 

Share this

Comments

Hello All,    To understand

Hello All, 

 

To understand DMA, I tried to implement sample dma module in x86 machine on (SUSE ). here is the code

<code>

 

#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/dma-mapping.h>

#include <linux/dmapool.h>

#include <linux/device.h>

 

static char *buffer= NULL;

 

static struct device *dev= NULL;

dma_addr_t mapping;

 

static int __init dma_init(void)

{

        buffer = kmalloc(10, GFP_KERNEL);

        if(buffer == NULL)

        {

                printk("kernel unbale to allocate memory for buffer\n");

                return -1;

        }

int ret = -1;

        dev = kzalloc(sizeof(*dev), GFP_KERNEL);

        if(dev == NULL)

        {

                kfree(buffer);

                return -1;

        }

 

 

        dev_set_name(dev, "asht_dma");

        ret = device_register(dev);

        printk("device reg ret =%d\n", ret);

        if(ret != 0)

        {

                kfree(buffer);

                kfree(dev);

                return -1;

        }

if(dma_set_mask(dev, 0xffffffff))

{

printk("DMA supports\n");

}

else

{

printk("DMA Not Supported\n");

kfree(buffer);

kfree(dev);

return -1;

 

}

mapping = dma_map_single(dev, buffer, 10, DMA_TO_DEVICE);

if(mapping == NULL)

        {

                printk("dma_map_single is failed !!!!!!!!!");

                kfree(buffer);

                kfree(dev);

                return 0;

        }

 

dma_unmap_single(dev, mapping, 10, DMA_TO_DEVICE);

 

 

printk("dma modlule inserted\n");

return 0;

}

 

 

static void __exit dma_exit(void)

{

 

                kfree(buffer);

                //device_unregister(dev);

dma_unmap_single(dev, mapping, 10, DMA_TO_DEVICE);

                kfree(dev);

printk("dma modlule removed\n");

}

 

module_init(dma_init);

module_exit(dma_exit);

 

MODULE_AUTHOR("ASHT");

MODULE_LICENSE("GPL");

</code>

 

#dmesg
device reg ret =0
DMA supports
BUG: unable to handle kernel NULL pointer dereference at 00000000
IP: [<c0109c8f>] nommu_map_single+0x36/0x97
*pdpt = 0000000037429001 *pde = 0000000000000000
Oops: 0000 [#1] SMP
last sysfs file: /sys/devices/virtual/net/lo/type
Modules linked in: dma1(N+) binfmt_misc(N) snd_pcm_oss(N) snd_mixer_oss(N) snd_seq(N) snd_seq_device(N) ipv6(N) i915(N) drm(N) af_packet(N) cpufreq_conservative(N) cpufreq_userspace(N) cpufreq_powersave(N) acpi_cpufreq(N) speedstep_lib(N) fuse(N) loop(N) dm_mod(N) snd_hda_intel(N) snd_pcm(N) snd_timer(N) snd_page_alloc(N) snd_hwdep(N) ppdev(N) snd(N) rtc_cmos(N) parport_pc(N) sr_mod(N) intel_agp(N) rtc_core(N) soundcore(N) button(N) agpgart(N) sg(N) i2c_i801(N) parport(N) serio_raw(N) pcspkr(N) rtc_lib(N) dcdbas(N) e1000e(N) cdrom(N) iTCO_wdt(N) i2c_core(N) iTCO_vendor_support(N) usbhid(N) hid(N) ff_memless(N) sd_mod(N) ehci_hcd(N) crc_t10dif(N) uhci_hcd(N) usbcore(N) edd(N) ext3(N) mbcache(N) jbd(N) fan(N) ide_pci_generic(N) ide_core(N) ahci(N) ata_generic(N) libata(N) scsi_mod(N) dock(N) thermal(N) processor(N) thermal_sys(N) hwmon(N)
Supported: No
Pid: 3948, comm: insmod Tainted: G          (2.6.27.7-9-pae #1)
EIP: 0060:[<c0109c8f>] EFLAGS: 00010246 CPU: 0
EIP is at nommu_map_single+0x36/0x97
EAX: 00000000 EBX: f7d7f800 ECX: 00000000 EDX: 37dc8a6a
ESI: 37dc8a60 EDI: 00000000 EBP: 0000000a ESP: ee1adee8
 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Process insmod (pid: 3948, ti=ee1ac000 task=ee16c530 task.ti=ee1ac000)
Stack: 00000000 00000000 00000000 00000000 00000000 fffffffc 00000000 c050a300
       fffffffc 00000000 f8cc5000 f8cc50e3 0000000a 00000001 f8c7e57c fffffffc
       c010112b f557c7f4 00000001 f8c7e44c 00000026 00000000 00000000 f8c7e588
Call Trace:
 [<f8cc50e3>] dma_init+0xe3/0x16f [dma1]
 [<c010112b>] _stext+0x3b/0x127
 [<c014ee38>] sys_init_module+0x8a/0x19e
 [<c0104c1b>] sysenter_do_call+0x12/0x2f
 [<ffffe430>] 0xffffe430
 =======================
Code: ec 1c 8b 6c 24 30 85 ed 75 0f ba 21 00 00 00 b8 25 a5 41 c0 e8 ee 36 02 00 85 db 74 51 8b 83 f4 00 00 00 89 ea 31 c9 01 f2 11 f9 <8b> 18 8b 40 04 39 c1 72 3a 77 04 39 da 76 34 83 f8 00 77 05 83
EIP: [<c0109c8f>] nommu_map_single+0x36/0x97 SS:ESP 0068:ee1adee8
---[ end trace 9b56c809dd172d32 ]---
This seems I'm getting OOPS at dma_map_single, Please suggest how to solve this
Regards,
Ashok

 

I'm not familiar with

I'm not familiar with PowerPC, so I can only speak in general terms.  Typically, there is no need to write a driver from scratch because someone probably already written it.  In terms using DMA in powerPC, there seems to be some code for the DMA controller in arch/powerpc/kernel/dma*.  May want to take a look.  Personally, I usually find it helpful to look at the code for a similar device that is already in the kernel tree.

Also, the code you have above.  device name is the only thing that was initialized in dev.  I would expect dma_map_single needs a lot more parameters initialized.

Good luck,

Steve