Date: Sun, 14 Oct 2012 10:13:51 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r241540 - in head/sys: amd64/pci i386/pci Message-ID: <201210141013.q9EADp7c039401@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Sun Oct 14 10:13:50 2012 New Revision: 241540 URL: http://svn.freebsd.org/changeset/base/241540 Log: pciereg_cfg*: use assembly to access the mem-mapped cfg space AMD BKDG for CPU families 10h and later requires that the memory mapped config is always read into or written from al/ax/eax register. Discussed with: kib, alc Reviewed by: kib (earlier version) MFC after: 25 days Modified: head/sys/amd64/pci/pci_cfgreg.c head/sys/i386/pci/pci_cfgreg.c Modified: head/sys/amd64/pci/pci_cfgreg.c ============================================================================== --- head/sys/amd64/pci/pci_cfgreg.c Sun Oct 14 10:12:32 2012 (r241539) +++ head/sys/amd64/pci/pci_cfgreg.c Sun Oct 14 10:13:50 2012 (r241540) @@ -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: head/sys/i386/pci/pci_cfgreg.c ============================================================================== --- head/sys/i386/pci/pci_cfgreg.c Sun Oct 14 10:12:32 2012 (r241539) +++ head/sys/i386/pci/pci_cfgreg.c Sun Oct 14 10:13:50 2012 (r241540) @@ -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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210141013.q9EADp7c039401>