Index: sys/dev/ntb/ntb_hw/ntb_hw_amd.h =================================================================== --- sys/dev/ntb/ntb_hw/ntb_hw_amd.h +++ sys/dev/ntb/ntb_hw/ntb_hw_amd.h @@ -48,7 +48,8 @@ #define NTB_HW_AMD_H #define NTB_HW_AMD_VENDOR_ID 0x1022 -#define NTB_HW_AMD_DEVICE_ID 0x145B +#define NTB_HW_AMD_DEVICE_ID1 0x145B +#define NTB_HW_AMD_DEVICE_ID2 0x148B #define NTB_DEF_PEER_CNT 1 #define NTB_DEF_PEER_IDX 0 @@ -82,6 +83,8 @@ #define DB_MASK_UNLOCK(sc) mtx_unlock_spin(&(sc)->db_mask_lock) #define DB_MASK_ASSERT(sc, f) mtx_assert(&(sc)->db_mask_lock, (f)) +#define QUIRK_MW0_32BIT 0x01 + /* amd_ntb_conn_type are hardware numbers, cannot change. */ enum amd_ntb_conn_type { NTB_CONN_NONE = -1, @@ -103,8 +106,13 @@ }; struct amd_ntb_hw_info { - uint32_t device_id; - const char *desc; + uint16_t device_id; + uint8_t mw_count; + uint8_t bar_start_idx; + uint8_t spad_count; + uint8_t db_count; + uint8_t quirks; + char *desc; }; struct amd_ntb_pci_bar_info { @@ -136,7 +144,10 @@ enum { /* AMD NTB Capability */ - AMD_MW_CNT = 3, + AMD_MW_CNT1 = 3, + AMD_MW_CNT2 = 2, + AMD_BAR_START_IDX1 = 1, + AMD_BAR_START_IDX2 = 2, AMD_DB_CNT = 16, AMD_MSIX_VECTOR_CNT = 24, AMD_SPADS_CNT = 16, @@ -218,6 +229,25 @@ AMD_PEER_OFFSET = 0x400, }; +struct amd_ntb_hw_info amd_ntb_hw_info_list[] = { + + { .device_id = NTB_HW_AMD_DEVICE_ID1, + .mw_count = AMD_MW_CNT1, + .bar_start_idx = AMD_BAR_START_IDX1, + .spad_count = AMD_SPADS_CNT, + .db_count = AMD_DB_CNT, + .quirks = QUIRK_MW0_32BIT, + .desc = "AMD Non-Transparent Bridge"}, + + { .device_id = NTB_HW_AMD_DEVICE_ID2, + .mw_count = AMD_MW_CNT2, + .bar_start_idx = AMD_BAR_START_IDX2, + .spad_count = AMD_SPADS_CNT, + .db_count = AMD_DB_CNT, + .quirks = 0, + .desc = "AMD Non-Transparent Bridge"}, +}; + struct amd_ntb_softc { /* ntb.c context. Do not move! Must go first! */ void *ntb_store; @@ -232,9 +262,7 @@ struct callout hb_timer; - uint8_t mw_count; - uint8_t spad_count; - uint8_t db_count; + struct amd_ntb_hw_info *hw_info; uint8_t msix_vec_count; struct mtx db_mask_lock; Index: sys/dev/ntb/ntb_hw/ntb_hw_amd.c =================================================================== --- sys/dev/ntb/ntb_hw/ntb_hw_amd.c +++ sys/dev/ntb/ntb_hw/ntb_hw_amd.c @@ -81,8 +81,12 @@ MALLOC_DEFINE(M_AMD_NTB, "amd_ntb_hw", "amd_ntb_hw driver memory allocations"); struct pci_device_table amd_ntb_devs[] = { - { PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID), - PCI_DESCR("AMD Non-Transparent Bridge") } + { PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID1), + .driver_data = (uintptr_t)&amd_ntb_hw_info_list[0], + PCI_DESCR("AMD Non-Transparent Bridge")}, + { PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID2), + .driver_data = (uintptr_t)&amd_ntb_hw_info_list[1], + PCI_DESCR("AMD Non-Transparent Bridge")} }; static unsigned g_amd_ntb_hw_debug_level; @@ -274,7 +278,7 @@ amd_deinit_side_info(ntb); - /* Disable event interrupt */ + // Disable event interrupt ntb->int_mask |= AMD_EVENT_INTMASK; amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask); @@ -299,7 +303,7 @@ { struct amd_ntb_softc *ntb = device_get_softc(dev); - return (ntb->mw_count); + return (ntb->hw_info->mw_count); } static int @@ -310,10 +314,10 @@ struct amd_ntb_softc *ntb = device_get_softc(dev); struct amd_ntb_pci_bar_info *bar_info; - if (mw_idx < 0 || mw_idx >= ntb->mw_count) + if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count) return (EINVAL); - bar_info = &ntb->bar_info[mw_idx+1]; + bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx]; if (base != NULL) *base = bar_info->pbase; @@ -331,10 +335,15 @@ *align_size = 1; if (plimit != NULL) { - if (mw_idx != 0) - *plimit = BUS_SPACE_MAXADDR; - else + /* + * For Device ID 0x145B (which has 3 memory windows), + * memory window 0 uses a 32-bit bar. The remaining + * cases all uses 64-bit bar + */ + if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT)) *plimit = BUS_SPACE_MAXADDR_32BIT; + else + *plimit = BUS_SPACE_MAXADDR; } return (0); @@ -346,12 +355,12 @@ struct amd_ntb_softc *ntb = device_get_softc(dev); struct amd_ntb_pci_bar_info *bar_info; - if (mw_idx < 0 || mw_idx >= ntb->mw_count) + if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count) return (EINVAL); - bar_info = &ntb->bar_info[mw_idx+1]; + bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx]; - /* make sure the range fits in the usable mw size */ + // make sure the range fits in the usable mw size if (size > bar_info->size) { amd_ntb_printf(0, "%s: size 0x%x greater than mw_size 0x%x\n", __func__, (uint32_t)size, (uint32_t)bar_info->size); @@ -373,17 +382,25 @@ __func__, mw_idx, bar_info->xlat_off, amd_ntb_peer_reg_read(8, bar_info->xlat_off), (void *)addr); - /* set and verify setting the limit */ - if (mw_idx != 0) { - amd_ntb_reg_write(8, bar_info->limit_off, (uint64_t)size); - amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%jx limit 0x%x\n", - __func__, bar_info->limit_off, - amd_ntb_peer_reg_read(8, bar_info->limit_off), (uint32_t)size); - } else { + /* + * set and verify setting the limit + * + * For Device ID 0x145B (which has 3 memory windows), + * memory window 0 uses a 32-bit bar. The remaining + * cases all uses 64-bit bar + */ + if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT)) { amd_ntb_reg_write(4, bar_info->limit_off, (uint64_t)size); amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%x limit 0x%x\n", __func__, bar_info->limit_off, - amd_ntb_peer_reg_read(4, bar_info->limit_off), (uint32_t)size); + amd_ntb_peer_reg_read(4, bar_info->limit_off), + (uint32_t)size); + } else { + amd_ntb_reg_write(8, bar_info->limit_off, (uint64_t)size); + amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%lx limit 0x%x\n", + __func__, bar_info->limit_off, + amd_ntb_peer_reg_read(8, bar_info->limit_off), + (uint32_t)size); } return (0); @@ -396,7 +413,7 @@ amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx); - if (mw_idx < 0 || mw_idx >= ntb->mw_count) + if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count) return (EINVAL); return (amd_ntb_mw_set_trans(dev, mw_idx, 0, 0)); @@ -409,10 +426,10 @@ struct amd_ntb_pci_bar_info *bar_info; int rc; - if (mw_idx < 0 || mw_idx >= ntb->mw_count) + if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count) return (EINVAL); - bar_info = &ntb->bar_info[mw_idx+1]; + bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx]; if (mode == bar_info->map_mode) return (0); @@ -431,10 +448,10 @@ amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx); - if (mw_idx < 0 || mw_idx >= ntb->mw_count) + if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count) return (EINVAL); - bar_info = &ntb->bar_info[mw_idx+1]; + bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx]; *mode = bar_info->map_mode; return (0); @@ -448,9 +465,10 @@ { struct amd_ntb_softc *ntb = device_get_softc(dev); - amd_ntb_printf(1, "%s: db_count 0x%x\n", __func__, ntb->db_count); + amd_ntb_printf(1, "%s: db_count 0x%x\n", __func__, + ntb->hw_info->db_count); - return (ntb->db_count); + return (ntb->hw_info->db_count); } static uint64_t @@ -470,9 +488,9 @@ struct amd_ntb_softc *ntb = device_get_softc(dev); amd_ntb_printf(1, "%s: vector %d db_count 0x%x db_valid_mask 0x%x\n", - __func__, vector, ntb->db_count, ntb->db_valid_mask); + __func__, vector, ntb->hw_info->db_count, ntb->db_valid_mask); - if (vector < 0 || vector >= ntb->db_count) + if (vector < 0 || vector >= ntb->hw_info->db_count) return (0); return (ntb->db_valid_mask & (1 << vector)); @@ -545,9 +563,10 @@ { struct amd_ntb_softc *ntb = device_get_softc(dev); - amd_ntb_printf(1, "%s: spad_count 0x%x\n", __func__, ntb->spad_count); + amd_ntb_printf(1, "%s: spad_count 0x%x\n", __func__, + ntb->hw_info->spad_count); - return (ntb->spad_count); + return (ntb->hw_info->spad_count); } static int @@ -558,7 +577,7 @@ amd_ntb_printf(2, "%s: idx %d\n", __func__, idx); - if (idx < 0 || idx >= ntb->spad_count) + if (idx < 0 || idx >= ntb->hw_info->spad_count) return (EINVAL); offset = ntb->self_spad + (idx << 2); @@ -576,7 +595,7 @@ amd_ntb_printf(2, "%s: idx %d\n", __func__, idx); - if (idx < 0 || idx >= ntb->spad_count) + if (idx < 0 || idx >= ntb->hw_info->spad_count) return (EINVAL); offset = ntb->self_spad + (idx << 2); @@ -591,7 +610,7 @@ { uint8_t i; - for (i = 0; i < ntb->spad_count; i++) + for (i = 0; i < ntb->hw_info->spad_count; i++) amd_ntb_spad_write(ntb->device, i, 0); } @@ -603,7 +622,7 @@ amd_ntb_printf(2, "%s: idx %d\n", __func__, idx); - if (idx < 0 || idx >= ntb->spad_count) + if (idx < 0 || idx >= ntb->hw_info->spad_count) return (EINVAL); offset = ntb->peer_spad + (idx << 2); @@ -621,7 +640,7 @@ amd_ntb_printf(2, "%s: idx %d\n", __func__, idx); - if (idx < 0 || idx >= ntb->spad_count) + if (idx < 0 || idx >= ntb->hw_info->spad_count) return (EINVAL); offset = ntb->peer_spad + (idx << 2); @@ -662,11 +681,11 @@ } sbuf_printf(sb, "AMD Memory window count: %d\n", - ntb->mw_count); + ntb->hw_info->mw_count); sbuf_printf(sb, "AMD Spad count: %d\n", - ntb->spad_count); + ntb->hw_info->spad_count); sbuf_printf(sb, "AMD Doorbell count: %d\n", - ntb->db_count); + ntb->hw_info->db_count); sbuf_printf(sb, "AMD MSI-X vec count: %d\n\n", ntb->msix_vec_count); sbuf_printf(sb, "AMD Doorbell valid mask: 0x%x\n", @@ -774,7 +793,7 @@ static void amd_ntb_irq_isr(void *arg) { - /* If we couldn't set up MSI-X, we only have the one vector. */ + // If we couldn't set up MSI-X, we only have the one vector. amd_ntb_interrupt(arg, 0); } @@ -817,7 +836,7 @@ for (i = 0; i < num_vectors; i++) { - /* RID should be 0 for intx */ + // RID should be 0 for intx if (intx) ntb->int_info[i].rid = i; else @@ -902,15 +921,15 @@ * Minimum necessary MSI-X message count should be equal to db_count */ supported_vectors = pci_msix_count(ntb->device); - num_vectors = MIN(supported_vectors, ntb->db_count); - if (num_vectors < ntb->db_count) { + num_vectors = MIN(supported_vectors, ntb->hw_info->db_count); + if (num_vectors < ntb->hw_info->db_count) { amd_ntb_printf(0, "No minimum msix: supported %d db %d\n", - supported_vectors, ntb->db_count); + supported_vectors, ntb->hw_info->db_count); msi = true; goto err_msix_enable; } - /* Allocate the necessary number of MSI-x messages */ + // Allocate the necessary number of MSI-x messages rc = pci_alloc_msix(ntb->device, &num_vectors); if (rc != 0) { amd_ntb_printf(0, "Error allocating msix vectors: %d\n", rc); @@ -918,12 +937,12 @@ goto err_msix_enable; } - if (num_vectors < ntb->db_count) { + if (num_vectors < ntb->hw_info->db_count) { amd_ntb_printf(0, "Allocated only %d MSI-X\n", num_vectors); msi = true; /* - * Else set ntb->db_count = ntb->msix_vec_count = num_vectors, - * msi=false and dont release msi + * Else set ntb->hw_info->db_count = ntb->msix_vec_count = + * num_vectors, msi=false and dont release msi */ } @@ -942,16 +961,16 @@ } } - ntb->db_count = ntb->msix_vec_count = num_vectors; + ntb->hw_info->db_count = ntb->msix_vec_count = num_vectors; if (intx) { num_vectors = 1; - ntb->db_count = 1; + ntb->hw_info->db_count = 1; ntb->msix_vec_count = 0; } amd_ntb_printf(0, "%s: db %d msix %d msi %d intx %d\n", - __func__, ntb->db_count, ntb->msix_vec_count, (int)msi, (int)intx); + __func__, ntb->hw_info->db_count, ntb->msix_vec_count, (int)msi, (int)intx); rc = amd_ntb_setup_isr(ntb, num_vectors, msi, intx); if (rc != 0) { @@ -968,7 +987,7 @@ struct amd_ntb_int_info *current_int; int i; - /* Mask all doorbell interrupts */ + // Mask all doorbell interrupts ntb->db_mask = ntb->db_valid_mask; amd_ntb_reg_write(4, AMD_DBMASK_OFFSET, ntb->db_mask); @@ -1002,16 +1021,13 @@ static int amd_ntb_init_dev(struct amd_ntb_softc *ntb) { - ntb->mw_count = AMD_MW_CNT; - ntb->spad_count = AMD_SPADS_CNT; - ntb->db_count = AMD_DB_CNT; - ntb->db_valid_mask = (1ull << ntb->db_count) - 1; + ntb->db_valid_mask = (1ull << ntb->hw_info->db_count) - 1; mtx_init(&ntb->db_mask_lock, "amd ntb db bits", NULL, MTX_SPIN); switch (ntb->conn_type) { case NTB_CONN_PRI: case NTB_CONN_SEC: - ntb->spad_count >>= 1; + ntb->hw_info->spad_count >>= 1; if (ntb->conn_type == NTB_CONN_PRI) { ntb->self_spad = 0; @@ -1099,13 +1115,13 @@ { int rc = 0; - /* NTB Config/Control registers - BAR 0 */ + // NTB Config/Control registers - BAR 0 ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); rc = map_bar(ntb, &ntb->bar_info[NTB_CONFIG_BAR]); if (rc != 0) goto out; - /* Memory Window 0 BAR - BAR 1*/ + // Memory Window 0 BAR - BAR 1 ntb->bar_info[NTB_BAR_1].pci_resource_id = PCIR_BAR(1); rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_1]); if (rc != 0) @@ -1113,7 +1129,7 @@ ntb->bar_info[NTB_BAR_1].xlat_off = AMD_BAR1XLAT_OFFSET; ntb->bar_info[NTB_BAR_1].limit_off = AMD_BAR1LMT_OFFSET; - /* Memory Window 1 BAR - BAR 2&3 */ + // Memory Window 1 BAR - BAR 2&3 ntb->bar_info[NTB_BAR_2].pci_resource_id = PCIR_BAR(2); rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_2]); if (rc != 0) @@ -1121,7 +1137,7 @@ ntb->bar_info[NTB_BAR_2].xlat_off = AMD_BAR23XLAT_OFFSET; ntb->bar_info[NTB_BAR_2].limit_off = AMD_BAR23LMT_OFFSET; - /* Memory Window 2 BAR - BAR 4&5 */ + // Memory Window 2 BAR - BAR 4&5 ntb->bar_info[NTB_BAR_3].pci_resource_id = PCIR_BAR(4); rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_3]); if (rc != 0) @@ -1153,12 +1169,14 @@ static int amd_ntb_probe(device_t device) { + struct amd_ntb_softc *ntb = device_get_softc(device); const struct pci_device_table *tbl; tbl = PCI_MATCH(device, amd_ntb_devs); if (tbl == NULL) return (ENXIO); + ntb->hw_info = (struct amd_ntb_hw_info *)tbl->driver_data; device_set_desc(device, tbl->descr); return (BUS_PROBE_GENERIC); @@ -1172,7 +1190,7 @@ ntb->device = device; - /* Enable PCI bus mastering for "device" */ + // Enable PCI bus mastering for "device" pci_enable_busmaster(ntb->device); error = amd_ntb_map_pci_bars(ntb); @@ -1189,7 +1207,7 @@ amd_ntb_sysctl_init(ntb); - /* Attach children to this controller */ + // Attach children to this controller error = ntb_register_device(device); out: @@ -1216,16 +1234,16 @@ } static device_method_t ntb_amd_methods[] = { - /* Device interface */ + // Device interface DEVMETHOD(device_probe, amd_ntb_probe), DEVMETHOD(device_attach, amd_ntb_attach), DEVMETHOD(device_detach, amd_ntb_detach), - /* Bus interface */ + // Bus interface DEVMETHOD(bus_child_location_str, ntb_child_location_str), DEVMETHOD(bus_print_child, ntb_print_child), - /* NTB interface */ + // NTB interface DEVMETHOD(ntb_port_number, amd_ntb_port_number), DEVMETHOD(ntb_peer_port_count, amd_ntb_peer_port_count), DEVMETHOD(ntb_peer_port_number, amd_ntb_peer_port_number),