git: 59f6ddb2bc9c - main - Use pmap_qenter in the N1SDP PCIe driver

Andrew Turner andrew at FreeBSD.org
Thu Feb 25 12:46:33 UTC 2021


The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86

commit 59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86
Author:     Andrew Turner <andrew at FreeBSD.org>
AuthorDate: 2021-02-23 12:34:45 +0000
Commit:     Andrew Turner <andrew at FreeBSD.org>
CommitDate: 2021-02-25 12:38:05 +0000

    Use pmap_qenter in the N1SDP PCIe driver
    
    In the Neoverse N1 SDP PCIe driver we need to map a page shared
    between the firmware and the kernel. Previously we would use
    pmap_kenter for this, however as this is not standardised between
    architectures switch to the common pmap_qenter.
    
    While here fix the error handling code to clean up on failure.
    
    Reviewed by:    br
    Sponsored by:   Innovate UK
    Differential Revision:  https://reviews.freebsd.org/D28890
---
 sys/dev/pci/controller/pci_n1sdp.c | 39 +++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/sys/dev/pci/controller/pci_n1sdp.c b/sys/dev/pci/controller/pci_n1sdp.c
index d51641c432f4..74d893ff1288 100644
--- a/sys/dev/pci/controller/pci_n1sdp.c
+++ b/sys/dev/pci/controller/pci_n1sdp.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 #include <vm/vm_page.h>
+#include <vm/vm_phys.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
 #include <contrib/dev/acpica/include/accommon.h>
@@ -66,6 +67,9 @@ __FBSDID("$FreeBSD$");
 #define	BDF_TABLE_SIZE		(16 * 1024)
 #define	PCI_CFG_SPACE_SIZE	0x1000
 
+_Static_assert(BDF_TABLE_SIZE >= PAGE_SIZE,
+    "pci_n1sdp.c assumes a 4k or 16k page size when mapping the shared data");
+
 struct pcie_discovery_data {
 	uint32_t rc_base_addr;
 	uint32_t nr_bdfs;
@@ -85,30 +89,40 @@ n1sdp_init(struct generic_pcie_n1sdp_softc *sc)
 	vm_offset_t vaddr;
 	vm_paddr_t paddr_rc;
 	vm_paddr_t paddr;
+	vm_page_t m[BDF_TABLE_SIZE / PAGE_SIZE];
 	int table_count;
 	int bdfs_size;
 	int error, i;
 
 	paddr = AP_NS_SHARED_MEM_BASE + sc->acpi.segment * BDF_TABLE_SIZE;
+	vm_phys_fictitious_reg_range(paddr, paddr + BDF_TABLE_SIZE,
+	    VM_MEMATTR_UNCACHEABLE);
+
+	for (i = 0; i < nitems(m); i++) {
+		m[i] = PHYS_TO_VM_PAGE(paddr + i * PAGE_SIZE);
+		MPASS(m[i] != NULL);
+	}
+
 	vaddr = kva_alloc((vm_size_t)BDF_TABLE_SIZE);
 	if (vaddr == 0) {
 		printf("%s: Can't allocate KVA memory.", __func__);
-		return (ENXIO);
+		error = ENXIO;
+		goto out;
 	}
-	pmap_kenter(vaddr, (vm_size_t)BDF_TABLE_SIZE, paddr,
-	    VM_MEMATTR_UNCACHEABLE);
+	pmap_qenter(vaddr, m, nitems(m));
 
 	shared_data = (struct pcie_discovery_data *)vaddr;
-	bdfs_size = sizeof(struct pcie_discovery_data) +
-	    sizeof(uint32_t) * shared_data->nr_bdfs;
-	sc->n1_discovery_data = malloc(bdfs_size, M_DEVBUF, M_WAITOK | M_ZERO);
-	memcpy(sc->n1_discovery_data, shared_data, bdfs_size);
-
 	paddr_rc = (vm_offset_t)shared_data->rc_base_addr;
 	error = bus_space_map(sc->acpi.base.bst, paddr_rc, PCI_CFG_SPACE_SIZE,
 	    0, &sc->n1_bsh);
 	if (error != 0)
-		return (error);
+		goto out_pmap;
+
+	bdfs_size = sizeof(struct pcie_discovery_data) +
+	    sizeof(uint32_t) * shared_data->nr_bdfs;
+	sc->n1_discovery_data = malloc(bdfs_size, M_DEVBUF,
+	    M_WAITOK | M_ZERO);
+	memcpy(sc->n1_discovery_data, shared_data, bdfs_size);
 
 	if (bootverbose) {
 		table_count = sc->n1_discovery_data->nr_bdfs;
@@ -117,10 +131,13 @@ n1sdp_init(struct generic_pcie_n1sdp_softc *sc)
 			    sc->n1_discovery_data->valid_bdfs[i]);
 	}
 
-	pmap_kremove(vaddr);
+out_pmap:
+	pmap_qremove(vaddr, nitems(m));
 	kva_free(vaddr, (vm_size_t)BDF_TABLE_SIZE);
 
-	return (0);
+out:
+	vm_phys_fictitious_unreg_range(paddr, paddr + BDF_TABLE_SIZE);
+	return (error);
 }
 
 static int


More information about the dev-commits-src-main mailing list