diff --git a/sys/dev/pci/controller/pci_n1sdp.c b/sys/dev/pci/controller/pci_n1sdp.c --- a/sys/dev/pci/controller/pci_n1sdp.c +++ b/sys/dev/pci/controller/pci_n1sdp.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,9 @@ #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 @@ 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 @@ 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