{"id":2317,"date":"2009-04-07T17:53:04","date_gmt":"2009-04-07T08:53:04","guid":{"rendered":"http:\/\/yasu2.prosou.nu\/blog\/index.php\/2009\/04\/07\/linux_msi\/"},"modified":"2009-04-07T17:53:04","modified_gmt":"2009-04-07T08:53:04","slug":"linux_msi","status":"publish","type":"post","link":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/2009\/04\/07\/2317\/","title":{"rendered":"Linux + MSI"},"content":{"rendered":"<p>\nStarted working with my device driver + PCIe interface task again, and yesterday I wrote my ioctl() handler. It was an easy task, and now I&#8217;m trying on interrupt handling.<\/p>\n<p>\nMSI (Message Signaled Interrupt) is a new way of PCI interruption, that issues an interrupt by a write request to a device specific address in memory address space, instead to assert INTA#.<\/p>\n<p>\nThere&#8217;s &#8220;MSI capability register&#8221; in the PCI configuration space, beginning at 0x48 in my case.  To find the register, (i) check the pointer at 0x34. (ii) 0x34 has a pointer (0x40) to next register. (iii) 0x40 has a capability ID(01), but this isn&#8217;t for MSI. 0x41 has a pointer to next, 0x48. (iii) 0x48 is the capability ID for MSI (0x05),  but 0x4a and 0x4b must be &#8220;0x81 0x01&#8221; if MSI is enabled&#8230;\n<\/p>\n<pre>\n02:00.0 RAM memory: Xilinx Corporation Device 0007\n0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n00: ee 10 07 00 07 00 10 00 00 00 00 05 10 00 00 00\n10: 04 00 20 e3 00 00 00 00 04 10 20 e3 00 00 00 00\n20: 00 00 00 00 00 00 00 00 00 00 00 00 ee 10 07 00\n30: 00 00 f0 ff 40 00 00 00 00 00 00 00 0b 01 00 00\n40: 01 48 03 08 00 00 00 00 05 60 80 01 00 00 00 00\n50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n60: 10 00 01 00 ea 8f 2c 01 10 29 00 00 41 f4 03 00\n70: 40 00 41 10 00 00 00 00 00 00 00 00 00 00 00 00\n<\/pre>\n<p>\nSo I added a pci_enable_msi() call in my driver initialization routine, and I&#8217;ve got it! The address and message to fire an interrupt are 0x00000000fee0f00c (at 0x4c-0x53) and 0x41b1 (at 0x54).<\/p>\n<pre>\n02:00.0 RAM memory: Xilinx Corporation Device 0007\n0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n00: ee 10 07 00 07 04 10 00 00 00 00 05 10 00 00 00\n10: 04 00 20 e3 00 00 00 00 04 10 20 e3 00 00 00 00\n20: 00 00 00 00 00 00 00 00 00 00 00 00 ee 10 07 00\n30: 00 00 f0 ff 40 00 00 00 00 00 00 00 0b 01 00 00\n40: 01 48 03 08 00 00 00 00 05 60 81 01 0c f0 e0 fe\n50: 00 00 00 00 b1 41 00 00 01 00 00 00 00 00 00 00\n60: 10 00 01 00 ea 8f 2c 01 10 29 00 00 41 f4 03 00\n70: 40 00 41 10 00 00 00 00 00 00 00 00 00 00 00 00\n<\/pre>\n<p>\nAdditionally, the link status register is located at 0x70 (in the PCIe function block: cap ID 0x10 at 0x60), and &#8220;0x0040&#8221; means that the PCIe interface is operating at x4 mode (0x**1* for x1, 0x**8* for x8).<\/p>\n<p>\nFYI: The Virtex-5 PCIe configuration space map is available in <a href=\"http:\/\/www.xilinx.com\/support\/documentation\/ip_documentation\/pcie_blk_plus_ug341.pdf\">Xilinx UG341<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Started working with my device driver + PCIe interface task again, and yesterday I wrote my ioctl() handler. I &hellip; <a href=\"https:\/\/yasu2.prosou.nu\/blog\/index.php\/2009\/04\/07\/2317\/\" class=\"more-link\"><span class=\"screen-reader-text\">&#8220;Linux + MSI&#8221; \u306e<\/span>\u7d9a\u304d\u3092\u8aad\u3080<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[6,4],"tags":[],"class_list":["post-2317","post","type-post","status-publish","format-standard","hentry","category-unix-","category-4"],"_links":{"self":[{"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/2317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=2317"}],"version-history":[{"count":0,"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/2317\/revisions"}],"wp:attachment":[{"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=2317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=2317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yasu2.prosou.nu\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=2317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}