diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2021-02-23 12:34:45 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2021-02-25 12:38:05 +0000 |
commit | 59f6ddb2bc9c560c84b6ac30a2e1f140325f0a86 (patch) | |
tree | 4d75add13ec185144831b7753780866815add8af /sys/dev/pci | |
parent | 7a4dbffa4205fc274b4884a6332d4831c5791320 (diff) | |
download | src-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.c | 39 |
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 |