c - Address mapping of PCI-memory in Kernel space -


i'm trying read , write , pci-device loadable kernel module.

therefore follow post:

pci_enable_device(dev); pci_request_regions(dev, "expdev"); bar1 = pci_iomap(dev, 1, 0); // void iowrite32(u32 val, void __iomem *addr) iowrite32( 0xaaaaaaaa, bar1 + 0x060000);  /* offset device spec */ 

but @ end device doesn't work expected. address behind bar1 , found big value ffffbaaaaa004500.

at point don't understand happen there , right. can interpret bar1 address inside kernel address space points directly base address 0x60000 offset pci chip select address?

and how can value write bar1 + offset copied device? how mechanism work in behind of iowrite32 , pci_iomap?

thanks , regards

alex

ps: tested read same address successfully.


register description of pci device:

  • pcibar0 pci base address 0; used memory-mapped configuration registers
  • pcibar1 pci base address 1; used i/o-mapped configuration registers
  • pcibar2 pci base address 2; used local address space 0
  • pcibar3 pci base address 3; used local address space 1
  • pcibar4 unused base address
  • pcibar5 unused base address

hello again.

in last time tried several approaches communicate bar2 register without success. here actual code:

#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/sched.h>  module_license("gpl"); module_author("alex"); module_description("test module."); module_version("0.1");  #define dev_pci_vendorid 0x10b5 #define dev_pci_deviceid 0x1860  static struct pci_device_id pci_drvidtable[] = {   {     .vendor      = dev_pci_vendorid,      // vendor id     .device      = dev_pci_deviceid,      // device id     .subvendor   = pci_any_id,            // no subsystem available     .subdevice   = pci_any_id,            // no subsystem available     .class       = pci_class_not_defined, // no device class     .class_mask  = 0,                     // no device class     .driver_data = 0                      // no private data driver   },   { 0, }                                  // end of table };  struct pci_data {   /// io mapping pci config space   uint32_t *pciconfigaddr;   uint32_t *pcib2addr; //  void __iomem *pciconfigaddr;    wait_queue_head_t waitq;   uint8_t flag; } *data;  static irqreturn_t _expdev_irq (int irq, void *pdata) {   struct pci_data *data = pdata;    printk(kern_info "interrupt talks...\n");   data->flag = 1;   wake_up_interruptible( &data->waitq );    return irq_handled; }   static int _pci_probe ( struct pci_dev *pdev,              const struct pci_device_id *ent ) {   int ret = 0;   int i;   u16 reg_16;   unsigned long bas2addr;    data = kzalloc( sizeof(*data) , gfp_kernel );   if( !data )   {     printk(kern_err "failed allocate memory.\n");     return -enomem;   }    pci_set_drvdata(pdev, data);    // enabling device   ret = pci_enable_device(pdev);   if( ret )   {     printk(kern_err "failed enable pci device.\n");     goto no_enable;   }    pci_read_config_word(pdev,0,&reg_16);   printk(kern_info "vendorid. %x\n",reg_16);    // checking if pci-device reachable checking bar0 defined ,   // memory mapped   if( !(pci_resource_flags(pdev,0) & ioresource_mem) )   {     printk(kern_err "incorrect bar configuration.\n");     ret = -enodev;     goto bad_bar;   }    // taking ownership of memory region   ret = pcim_iomap_regions(pdev, 0b0100, "expdev"); //  ret = pci_request_regions(pdev,"expdev");   if( ret )   {     printk(kern_err "failed request regions.\n");     goto failed_request_regions;   }    bas2addr = pci_resource_start(pdev, 2);    reg_16 = 0xaa;   = 0x060000;   iowrite16( reg_16 , (unsigned long *)(bas2addr+i) );   printk( kern_info "bar2 register[0x%x] = 0x%x\n",           i, ioread32( (unsigned long *)(bas2addr+i) ) );    printk(kern_info "module initialised.\n");    return 0;    // error handling - backward disabling device failed_request_regions: bad_bar:   pci_disable_device(pdev); no_enable:   pci_set_drvdata(pdev, data);    return ret; }   static void _pci_remove( struct pci_dev *pdev ) {   free_irq(pdev->irq, data);   pci_disable_msi(pdev);   pci_clear_master(pdev);   pci_iounmap(pdev,data->pciconfigaddr);   pci_release_regions(pdev);   pci_disable_device(pdev);    printk(kern_info "pci-device removed.\n"); }   static struct pci_driver pci_drv = {   .name     = "expdev",   .id_table = pci_drvidtable,   .probe    = _pci_probe,   .remove   = _pci_remove, };  // module related functions ///////////////////////////////////////////////////  static int __init _module_init(void){    printk(kern_info "hello!\n");     pci_register_driver(&pci_drv);     return 0; }  static void __exit _module_exit(void){     pci_unregister_driver(&pci_drv);     printk(kern_info "goodbye!\n"); }  module_init(_module_init); module_exit(_module_exit); 

this responding output tail -f /var/log/kern.log

kernel: [  493.719999] hello! kernel: [  493.720071] expdev 0000:05:02.0: enabling device (0000 -> 0003) kernel: [  493.720845] vendorid. 10b5 kernel: [  493.722375] bug: unable handle kernel paging request @ 00000000eb060000 kernel: [  493.722381] ip: [<ffffffff8137aca8>] iowrite16+0x38/0x40 kernel: [  493.722388] pgd 0  kernel: [  493.722390] oops: 0002 [#1] smp  kernel: [  493.722394] modules linked in: expdev(ox+) rfcomm bnep bluetooth nvidia(pox) snd_hda_codec_hdmi joydev snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep snd_pcm coretemp snd_page_alloc snd_seq_midi snd_seq_midi_event snd_rawmidi gpio_ich kvm snd_seq snd_seq_device drm dcdbas snd_timer lpc_ich snd soundcore shpchp serio_raw ppdev i82975x_edac lp parport_pc edac_core parport mac_hid hid_generic usbhid hid psmouse ahci tg3 libahci ptp pps_core pata_acpi kernel: [  493.722429] cpu: 0 pid: 3542 comm: insmod tainted: p           ox 3.13.0-79-generic #123-ubuntu kernel: [  493.722431] hardware name: dell inc.                 precision workstation 390    /0dn075, bios 2.3.0  05/01/2007 kernel: [  493.722434] task: ffff8800549c3000 ti: ffff8800555e6000 task.ti: ffff8800555e6000 kernel: [  493.722436] rip: 0010:[<ffffffff8137aca8>]  [<ffffffff8137aca8>] iowrite16+0x38/0x40 kernel: [  493.722440] rsp: 0018:ffff8800555e7b88  eflags: 00010212 kernel: [  493.722442] rax: 00000000eb000000 rbx: ffff88007c2b4000 rcx: 0000000000000000 kernel: [  493.722444] rdx: 00000000eb060000 rsi: 00000000eb060000 rdi: 00000000000000aa kernel: [  493.722446] rbp: ffff8800555e7bb0 r08: 00000000ebffffff r09: 00000000ffffffec kernel: [  493.722448] r10: 0000000000003692 r11: 0000000000000000 r12: 00000000eb060000 kernel: [  493.722450] r13: ffff88007c2b4098 r14: ffff88007c2b4098 r15: ffffffffa022b140 kernel: [  493.722452] fs:  00007fa8053ef740(0000) gs:ffff88007f800000(0000) knlgs:0000000000000000 kernel: [  493.722454] cs:  0010 ds: 0000 es: 0000 cr0: 000000008005003b kernel: [  493.722456] cr2: 00000000eb060000 cr3: 000000005a74b000 cr4: 00000000000007f0 kernel: [  493.722458] stack: kernel: [  493.722460]  ffffffffa02291c4 00aa88007c2b4000 ffff88007c2b4000 0000000000000000 kernel: [  493.722464]  ffffffffa022b000 ffff8800555e7be8 ffffffff813ac8a5 ffffffff813adb45 kernel: [  493.722467]  ffff88007c2b4098 ffffffffffffffff ffff88007c2b4000 0000000000000017 kernel: [  493.722471] call trace: kernel: [  493.722477]  [<ffffffffa02291c4>] ? _pci_probe+0x114/0x215 [expdev] kernel: [  493.722481]  [<ffffffff813ac8a5>] local_pci_probe+0x45/0xa0 kernel: [  493.722484]  [<ffffffff813adb45>] ? pci_match_device+0xc5/0xd0 kernel: [  493.722487]  [<ffffffff813adc69>] pci_device_probe+0xd9/0x130 kernel: [  493.722492]  [<ffffffff8149a4bd>] driver_probe_device+0x12d/0x3e0 kernel: [  493.722495]  [<ffffffff8149a843>] __driver_attach+0x93/0xa0 kernel: [  493.722498]  [<ffffffff8149a7b0>] ? __device_attach+0x40/0x40 kernel: [  493.722501]  [<ffffffff81498403>] bus_for_each_dev+0x63/0xa0 kernel: [  493.722504]  [<ffffffff81499e6e>] driver_attach+0x1e/0x20 kernel: [  493.722507]  [<ffffffff81499a50>] bus_add_driver+0x180/0x250 kernel: [  493.722510]  [<ffffffffa0005000>] ? 0xffffffffa0004fff kernel: [  493.722514]  [<ffffffff8149aec4>] driver_register+0x64/0xf0 kernel: [  493.722517]  [<ffffffffa0005000>] ? 0xffffffffa0004fff kernel: [  493.722520]  [<ffffffff813ac23c>] __pci_register_driver+0x4c/0x50 kernel: [  493.722523]  [<ffffffffa000502c>] _module_init+0x2c/0x1000 [expdev] kernel: [  493.722528]  [<ffffffff8100214a>] do_one_initcall+0xfa/0x1b0 kernel: [  493.722532]  [<ffffffff810598f3>] ? set_memory_nx+0x43/0x50 kernel: [  493.722536]  [<ffffffff810e2b7d>] load_module+0x12ed/0x1b50 kernel: [  493.722540]  [<ffffffff810de5f0>] ? store_uevent+0x40/0x40 kernel: [  493.722544]  [<ffffffff810e3556>] sys_finit_module+0x86/0xb0 kernel: [  493.722548]  [<ffffffff817363dd>] system_call_fastpath+0x1a/0x1f kernel: [  493.722550] code: 81 fe 00 00 01 00 76 0b 0f b7 d6 89 f8 66 ef c3 0f 1f 00 55 48 c7 c6 b0 10 a9 81 48 89 d7 48 89 e5 e8 5d fe ff ff 5d c3 0f 1f 00 <66> 89 3e c3 0f 1f 40 00 48 81 fe ff ff 03 00 48 89 f2 77 2c 48  kernel: [  493.722583] rip  [<ffffffff8137aca8>] iowrite16+0x38/0x40 kernel: [  493.722586]  rsp <ffff8800555e7b88> kernel: [  493.722588] cr2: 00000000eb060000 kernel: [  493.722591] ---[ end trace 2d3dfa92998d58a7 ]--- 

according ian abbott tried approach successfully. don't understand mechanism behind works now. bar2 memory register type. approach uses ioremap , not memory-mapping. how access bar2 via memory-mapping?

#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h>  module_license("gpl"); module_author("alex"); module_description("test module."); module_version("0.1");  #define dev_pci_vendorid 0x10b5 #define dev_pci_deviceid 0x1860  static struct pci_device_id pci_drvidtable[] = {   {     .vendor      = dev_pci_vendorid,      // vendor id     .device      = dev_pci_deviceid,      // device id     .subvendor   = pci_any_id,            // no subsystem available     .subdevice   = pci_any_id,            // no subsystem available     .class       = pci_class_not_defined, // no device class     .class_mask  = 0,                     // no device class     .driver_data = 0                      // no private data driver   },   { 0, }                                  // end of table };  struct pci_data { //  struct pci_dev *pci_dev;    /// io mapping pci config space   uint32_t *pciconfigaddr;   uint32_t *pcib2addr;    wait_queue_head_t waitq;   uint8_t flag; } *data;  static int _pci_probe ( struct pci_dev *pdev,              const struct pci_device_id *ent ) {   int ret = 0;   int i;   u16 reg_16;   unsigned long *pbas2addr;    data = kzalloc( sizeof(*data) , gfp_kernel );   if( !data )   {     printk(kern_err "failed allocate memory.\n");     return -enomem;   }    pci_set_drvdata(pdev, data);    // enabling device   ret = pci_enable_device(pdev);   if( ret )   {     printk(kern_err "failed enable pci device.\n");     goto no_enable;   }    pci_read_config_word(pdev,0,&reg_16);   printk(kern_info "vendorid. %x\n",reg_16);    // checking if pci-device reachable checking bar0 defined ,   // memory mapped   if( !(pci_resource_flags(pdev,0) & ioresource_mem) )   {     printk(kern_err "incorrect bar configuration.\n");     ret = -enodev;     goto bad_bar;   }    // taking ownership of memory region   pbas2addr = pci_ioremap_bar(pdev, 2);    // void iowrite8(u8 val, void __iomem *addr)     ( = 0x060000; i<0x070000; i++ )     {       iowrite8( 0x11 , pbas2addr+i );     }    // further read/write function in kernel:   // inp,  readl,  readw,  readb,  ioread8,  ioread16,  ioread32   // outp, writel, writew, writeb, iowrite8, iowrite16, iowrite32  bad_bar:   pci_disable_device(pdev); no_enable:   pci_set_drvdata(pdev, data);    return ret; }  static void _pci_remove( struct pci_dev *pdev ) {   pci_disable_device(pdev);   printk(kern_info "pci-device removed.\n"); }  static struct pci_driver pci_drv = {   .name     = "expdev",   .id_table = pci_drvidtable,   .probe    = _pci_probe,   .remove   = _pci_remove, };  // module related functions ///////////////////////////////////////////////////  static int __init _module_init(void){    printk(kern_info "hello!\n");    pci_register_driver(&pci_drv);    return 0; }  static void __exit _module_exit(void){    pci_unregister_driver(&pci_drv);    printk(kern_info "goodbye!\n"); }  module_init(_module_init); module_exit(_module_exit); 

i'm @ end. think have follow docs doesn't work expected.

here code:

#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/sched.h>  #include <linux/delay.h>  module_license("gpl"); module_author("alex"); module_description("test module."); module_version("0.1");  #define dev_pci_vendorid 0x10b5 #define dev_pci_deviceid 0x1860  static struct pci_device_id pci_drvidtable[] = {   {     .vendor      = dev_pci_vendorid,      // vendor id     .device      = dev_pci_deviceid,        // device id     .subvendor   = pci_any_id,            // no subsystem available     .subdevice   = pci_any_id,            // no subsystem available     .class       = pci_class_not_defined, // no device class     .class_mask  = 0,                       // no device class     .driver_data = 0                        // no private data driver   },   { 0, } };  static int _pci_probe ( struct pci_dev *pdev,              const struct pci_device_id *ent ) {   int ret = 0;   int i;   unsigned long *pbas2addr;    // enabling device   ret = pci_enable_device(pdev);   if( ret )   {     printk(kern_err "failed enable pci device.\n");     goto no_enable;   }    pci_request_regions(pdev, "expdev");    // checking if pci-device reachable checking bar0 defined ,   // memory mapped   if( !(pci_resource_flags(pdev,0) & ioresource_mem) )   {     printk(kern_err "incorrect bar configuration.\n");     ret = -enodev;     goto bad_bar;   }    // taking ownership of memory region   pbas2addr = pci_ioremap_bar(pdev, 2);    printk(kern_info "bar2: %p\n",pbas2addr);    ( = 0x060000; i<0x070000; i++ )   {     iowrite8( 0x00 , pbas2addr+i );   }    // next write operations cause crashing the module   // load control word set icd in set-up-mode   iowrite32(0b01111000000101, pbas2addr+0x200014);   // load bit-stuffed set word   iowrite32(0b10110001001001101110000, pbas2addr+0x200018); // 39.5 mhz   // load control word set icd in set-up-mode   iowrite32(0b01111000000100, pbas2addr+0x200014);   msleep(10);   // load control word set icd in set-up-mode   iowrite32(0b01111000000000, pbas2addr+0x200014);    return 0;  bad_bar:   pci_disable_device(pdev);    return ret; }   static void _pci_remove( struct pci_dev *pdev ) {   pci_release_regions(pdev);   pci_disable_device(pdev);    printk(kern_info "pci-device removed.\n"); }  static struct pci_driver pci_drv = {   .name     = "expdev",   .id_table = pci_drvidtable,   .probe    = _pci_probe,   .remove   = _pci_remove, };  // module related functions      static int __init _module_init(void){    printk(kern_info "hello!\n");    pci_register_driver(&pci_drv);    return 0; }  static void __exit _module_exit(void){    pci_unregister_driver(&pci_drv);    printk(kern_info "goodbye!\n"); }  module_init(_module_init); module_exit(_module_exit); 

with for-loop:

kernel: [  467.545079] hello! kernel: [  467.545136] expdev 0000:05:02.0: enabling device (0000 -> 0003) kernel: [  467.546807] bar2: ffffc90006c00000 kernel: [  467.562146] pci-device removed. kernel: [  467.562489] goodbye! 

and can see outputs on device gpio.

if write higher addresses needed regarding device manual lkm crashes:

kernel: [ 1324.591578] hello! kernel: [ 1324.593300] bar2: ffffc90007c80000 kernel: [ 1324.605162] bug: unable handle kernel paging request @ ffffc90008c800a0 kernel: [ 1324.605168] ip: [<ffffffff8137ace8>] iowrite32+0x38/0x40 kernel: [ 1324.605175] pgd 7d00d067 pud 7d00e067 pmd 611e7067 pte 0 kernel: [ 1324.605179] oops: 0002 [#1] smp  kernel: [ 1324.605183] modules linked in: expdev(ox+) rfcomm bnep bluetooth nvidia(pox) snd_hda_codec_hdmi joydev snd_hda_codec_idt snd_hda_intel snd_hda_codec gpio_ich coretemp drm snd_seq_midi kvm snd_seq_midi_event dcdbas snd_rawmidi snd_hwdep lpc_ich snd_seq snd_pcm snd_seq_device snd_page_alloc shpchp ppdev serio_raw snd_timer lp snd soundcore mac_hid i82975x_edac edac_core parport_pc parport hid_generic usbhid hid psmouse ahci libahci pata_acpi tg3 ptp pps_core [last unloaded: expdev] kernel: [ 1324.605219] cpu: 0 pid: 3155 comm: insmod tainted: p           ox 3.13.0-79-generic #123-ubuntu kernel: [ 1324.605221] hardware name: dell inc.                 precision workstation 390    /0dn075, bios 2.3.0  05/01/2007 kernel: [ 1324.605224] task: ffff88007c048000 ti: ffff880061122000 task.ti: ffff880061122000 kernel: [ 1324.605226] rip: 0010:[<ffffffff8137ace8>]  [<ffffffff8137ace8>] iowrite32+0x38/0x40 kernel: [ 1324.605229] rsp: 0018:ffff880061123b90  eflags: 00010292 kernel: [ 1324.605231] rax: 0000000000000016 rbx: ffffc90008c800a0 rcx: 0000000000000000 kernel: [ 1324.605233] rdx: ffffc90008c800a0 rsi: ffffc90008c800a0 rdi: 0000000000001e05 kernel: [ 1324.605235] rbp: ffff880061123bb0 r08: 0000000000000096 r09: 0000000000000306 kernel: [ 1324.605237] r10: 0000000000000000 r11: ffff8800611238c6 r12: ffffc90007f80000 kernel: [ 1324.605239] r13: ffffc90007c80000 r14: ffff88007c2b4098 r15: ffffffffa01fc140 kernel: [ 1324.605242] fs:  00007fc6802cb740(0000) gs:ffff88007f800000(0000) knlgs:0000000000000000 kernel: [ 1324.605244] cs:  0010 ds: 0000 es: 0000 cr0: 0000000080050033 kernel: [ 1324.605246] cr2: ffffc90008c800a0 cr3: 0000000062f96000 cr4: 00000000000007f0 kernel: [ 1324.605248] stack: kernel: [ 1324.605249]  ffffffffa01fa0ec ffff88007c2b4000 0000000000000000 ffffffffa01fc000 kernel: [ 1324.605253]  ffff880061123be8 ffffffff813ac8a5 ffffffff813adb45 ffff88007c2b4098 kernel: [ 1324.605257]  ffffffffffffffff ffff88007c2b4000 0000000000000018 ffff880061123c30 kernel: [ 1324.605260] call trace: kernel: [ 1324.605267]  [<ffffffffa01fa0ec>] ? _pci_probe+0xbc/0x110 [expdev] kernel: [ 1324.605271]  [<ffffffff813ac8a5>] local_pci_probe+0x45/0xa0 kernel: [ 1324.605274]  [<ffffffff813adb45>] ? pci_match_device+0xc5/0xd0 kernel: [ 1324.605277]  [<ffffffff813adc69>] pci_device_probe+0xd9/0x130 kernel: [ 1324.605281]  [<ffffffff8149a4bd>] driver_probe_device+0x12d/0x3e0 kernel: [ 1324.605285]  [<ffffffff8149a843>] __driver_attach+0x93/0xa0 kernel: [ 1324.605288]  [<ffffffff8149a7b0>] ? __device_attach+0x40/0x40 kernel: [ 1324.605290]  [<ffffffff81498403>] bus_for_each_dev+0x63/0xa0 kernel: [ 1324.605293]  [<ffffffff81499e6e>] driver_attach+0x1e/0x20 kernel: [ 1324.605296]  [<ffffffff81499a50>] bus_add_driver+0x180/0x250 kernel: [ 1324.605300]  [<ffffffffa0006000>] ? 0xffffffffa0005fff kernel: [ 1324.605303]  [<ffffffff8149aec4>] driver_register+0x64/0xf0 kernel: [ 1324.605306]  [<ffffffffa0006000>] ? 0xffffffffa0005fff kernel: [ 1324.605309]  [<ffffffff813ac23c>] __pci_register_driver+0x4c/0x50 kernel: [ 1324.605313]  [<ffffffffa000602c>] _module_init+0x2c/0x1000 [expdev] kernel: [ 1324.605317]  [<ffffffff8100214a>] do_one_initcall+0xfa/0x1b0 kernel: [ 1324.605321]  [<ffffffff810598f3>] ? set_memory_nx+0x43/0x50 kernel: [ 1324.605326]  [<ffffffff810e2b7d>] load_module+0x12ed/0x1b50 kernel: [ 1324.605330]  [<ffffffff810de5f0>] ? store_uevent+0x40/0x40 kernel: [ 1324.605334]  [<ffffffff810e3556>] sys_finit_module+0x86/0xb0 kernel: [ 1324.605338]  [<ffffffff817363dd>] system_call_fastpath+0x1a/0x1f kernel: [ 1324.605340] code: 81 fe 00 00 01 00 76 0b 0f b7 d6 89 f8 ef c3 0f 1f 40 00 55 48 c7 c6 bf 10 a9 81 48 89 d7 48 89 e5 e8 1d fe ff ff 5d c3 0f 1f 00 <89> 3e c3 0f 1f 44 00 00 48 81 ff ff ff 03 00 77 37 48 81 ff 00  kernel: [ 1324.605373] rip  [<ffffffff8137ace8>] iowrite32+0x38/0x40 kernel: [ 1324.605376]  rsp <ffff880061123b90> kernel: [ 1324.605378] cr2: ffffc90008c800a0 kernel: [ 1324.605381] ---[ end trace 9b1029fd3f919791 ]--- 

rip - why. offset within limits of 16 mb.


Comments

Popular posts from this blog

Hatching array of circles in AutoCAD using c# -

ios - UITEXTFIELD InputView Uipicker not working in swift -

Python Pig Latin Translator -