svn commit: r241540 - in head/sys: amd64/pci i386/pci
Andriy Gapon
avg at FreeBSD.org
Sun Oct 14 10:13:51 UTC 2012
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;
}
More information about the svn-src-all
mailing list