aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2021-02-23 12:34:45 +0000
committerAndrew Turner <andrew@FreeBSD.org>2021-02-25 12:38:05 +0000
commit59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86 (patch)
tree4d75add13ec185144831b7753780866815add8af /sys/dev/pci
parent7a4dbffa4205fc274b4884a6332d4831c5791320 (diff)
downloadsrc-59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86.tar.gz
src-59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86.zip
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
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/controller/pci_n1sdp.c39
1 files 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