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
This commit is contained in:
Andrew Turner 2021-02-23 12:34:45 +00:00
parent 7a4dbffa42
commit 59f6ddb2bc

View File

@ -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