Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Nov 2012 12:04:03 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r242856 - in stable/9/sys: amd64/pci i386/pci
Message-ID:  <201211101204.qAAC43Xe001973@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 	}
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211101204.qAAC43Xe001973>