Author: avg
Date: Sat Nov 10 12:04:02 2012
New Revision: 242856
URL: http://svnweb.freebsd.org/changeset/base/242856

Log:
  MFC r241540: pciereg_cfg*: use assembly to access the mem-mapped cfg space

Modified:
  stable/9/sys/amd64/pci/pci_cfgreg.c
  stable/9/sys/i386/pci/pci_cfgreg.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/amd64/pci/pci_cfgreg.c
==============================================================================
--- stable/9/sys/amd64/pci/pci_cfgreg.c Sat Nov 10 11:55:52 2012        
(r242855)
+++ stable/9/sys/amd64/pci/pci_cfgreg.c Sat Nov 10 12:04:02 2012        
(r242856)
@@ -295,6 +295,13 @@ pcie_cfgregopen(uint64_t base, uint8_t m
        return (1);
 }
 
+/*
+ * AMD BIOS And Kernel Developer's Guides for CPU families starting with 10h
+ * have a requirement that all accesses to the memory mapped PCI configuration
+ * space are done using AX class of registers.
+ * Since other vendors do not currently have any contradicting requirements
+ * the AMD access pattern is applied universally.
+ */
 #define PCIE_VADDR(base, reg, bus, slot, func) \
        ((base)                         +       \
        ((((bus) & 0xff) << 20)         |       \
@@ -317,13 +324,16 @@ pciereg_cfgread(int bus, unsigned slot, 
 
        switch (bytes) {
        case 4:
-               data = *(volatile uint32_t *)(va);
+               __asm __volatile("mov %1, %%eax" : "=a" (data)
+                   : "m" (*(uint32_t *)va));
                break;
        case 2:
-               data = *(volatile uint16_t *)(va);
+               __asm __volatile("movzwl %1, %%eax" : "=a" (data)
+                   : "m" (*(uint16_t *)va));
                break;
        case 1:
-               data = *(volatile uint8_t *)(va);
+               __asm __volatile("movzbl %1, %%eax" : "=a" (data)
+                   : "m" (*(uint8_t *)va));
                break;
        }
 
@@ -344,13 +354,16 @@ pciereg_cfgwrite(int bus, unsigned slot,
 
        switch (bytes) {
        case 4:
-               *(volatile uint32_t *)(va) = data;
+               __asm __volatile("mov %%eax, %0" : "=m" (*(uint32_t *)va)
+                   : "a" (data));
                break;
        case 2:
-               *(volatile uint16_t *)(va) = data;
+               __asm __volatile("mov %%ax, %0" : "=m" (*(uint16_t *)va)
+                   : "a" (data));
                break;
        case 1:
-               *(volatile uint8_t *)(va) = data;
+               __asm __volatile("mov %%al, %0" : "=m" (*(uint8_t *)va)
+                   : "a" (data));
                break;
        }
 }

Modified: stable/9/sys/i386/pci/pci_cfgreg.c
==============================================================================
--- stable/9/sys/i386/pci/pci_cfgreg.c  Sat Nov 10 11:55:52 2012        
(r242855)
+++ stable/9/sys/i386/pci/pci_cfgreg.c  Sat Nov 10 12:04:02 2012        
(r242856)
@@ -652,6 +652,14 @@ pciereg_findelem(vm_paddr_t papage)
        return (elem);
 }
 
+/*
+ * AMD BIOS And Kernel Developer's Guides for CPU families starting with 10h
+ * have a requirement that all accesses to the memory mapped PCI configuration
+ * space are done using AX class of registers.
+ * Since other vendors do not currently have any contradicting requirements
+ * the AMD access pattern is applied universally.
+ */
+
 static int
 pciereg_cfgread(int bus, unsigned slot, unsigned func, unsigned reg,
     unsigned bytes)
@@ -673,13 +681,16 @@ pciereg_cfgread(int bus, unsigned slot, 
 
        switch (bytes) {
        case 4:
-               data = *(volatile uint32_t *)(va);
+               __asm __volatile("mov %1, %%eax" : "=a" (data)
+                   : "m" (*(uint32_t *)va));
                break;
        case 2:
-               data = *(volatile uint16_t *)(va);
+               __asm __volatile("movzwl %1, %%eax" : "=a" (data)
+                   : "m" (*(uint16_t *)va));
                break;
        case 1:
-               data = *(volatile uint8_t *)(va);
+               __asm __volatile("movzbl %1, %%eax" : "=a" (data)
+                   : "m" (*(uint8_t *)va));
                break;
        }
 
@@ -707,13 +718,16 @@ pciereg_cfgwrite(int bus, unsigned slot,
 
        switch (bytes) {
        case 4:
-               *(volatile uint32_t *)(va) = data;
+               __asm __volatile("mov %%eax, %0" : "=m" (*(uint32_t *)va)
+                   : "a" (data));
                break;
        case 2:
-               *(volatile uint16_t *)(va) = data;
+               __asm __volatile("mov %%ax, %0" : "=m" (*(uint16_t *)va)
+                   : "a" (data));
                break;
        case 1:
-               *(volatile uint8_t *)(va) = data;
+               __asm __volatile("mov %%al, %0" : "=m" (*(uint8_t *)va)
+                   : "a" (data));
                break;
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to