The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ntb/ntb_hw/ntb_hw_amd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * This file is provided under a dual BSD/GPLv2 license.  When using or
    3  * redistributing this file, you may do so under either license.
    4  *
    5  * GPL LICENSE SUMMARY
    6  *
    7  * Copyright (C) 2019 Advanced Micro Devices, Inc.
    8  *
    9  * This program is free software; you can redistribute it and/or modify
   10  * it under the terms of version 2 of the GNU General Public License as
   11  * published by the Free Software Foundation.
   12  *
   13  * BSD LICENSE
   14  *
   15  * Copyright (c) 2019 Advanced Micro Devices, Inc.
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice, this list of conditions and the following disclaimer.
   22  * 2. Redistributions in binary form must reproduce the above copyright
   23  *    notice, this list of conditions and the following disclaimer in the
   24  *    documentation and/or other materials provided with the distribution.
   25  * 3. Neither the name of AMD corporation nor the names of its
   26  *    contributors may be used to endorse or promote products derived
   27  *    from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   39  * SUCH DAMAGE.
   40  *
   41  * Contact Information :
   42  * Rajesh Kumar <rajesh1.kumar@amd.com>
   43  */
   44 
   45 /*
   46  * The Non-Transparent Bridge (NTB) is a device that allows you to connect
   47  * two or more systems using a PCI-e links, providing remote memory access.
   48  *
   49  * This module contains a driver for NTB hardware in AMD CPUs
   50  *
   51  * Much of the code in this module is shared with Linux. Any patches may
   52  * be picked up and redistributed in Linux with a dual GPL/BSD license.
   53  */
   54 
   55 #include <sys/cdefs.h>
   56 __FBSDID("$FreeBSD$");
   57 
   58 #include <sys/param.h>
   59 #include <sys/kernel.h>
   60 #include <sys/systm.h>
   61 #include <sys/bus.h>
   62 #include <sys/lock.h>
   63 #include <sys/malloc.h>
   64 #include <sys/module.h>
   65 #include <sys/mutex.h>
   66 #include <sys/rman.h>
   67 #include <sys/sbuf.h>
   68 #include <sys/sysctl.h>
   69 
   70 #include <vm/vm.h>
   71 #include <vm/pmap.h>
   72 
   73 #include <machine/bus.h>
   74 
   75 #include <dev/pci/pcireg.h>
   76 #include <dev/pci/pcivar.h>
   77 
   78 #include "ntb_hw_amd.h"
   79 #include "dev/ntb/ntb.h"
   80 
   81 MALLOC_DEFINE(M_AMD_NTB, "amd_ntb_hw", "amd_ntb_hw driver memory allocations");
   82 
   83 static const struct amd_ntb_hw_info amd_ntb_hw_info_list[] = {
   84         { .vendor_id = NTB_HW_AMD_VENDOR_ID,
   85           .device_id = NTB_HW_AMD_DEVICE_ID1,
   86           .mw_count = 3,
   87           .bar_start_idx = 1,
   88           .spad_count = 16,
   89           .db_count = 16,
   90           .msix_vector_count = 24,
   91           .quirks = QUIRK_MW0_32BIT,
   92           .desc = "AMD Non-Transparent Bridge"},
   93 
   94         { .vendor_id = NTB_HW_AMD_VENDOR_ID,
   95           .device_id = NTB_HW_AMD_DEVICE_ID2,
   96           .mw_count = 2,
   97           .bar_start_idx = 2,
   98           .spad_count = 16,
   99           .db_count = 16,
  100           .msix_vector_count = 24,
  101           .quirks = 0,
  102           .desc = "AMD Non-Transparent Bridge"},
  103 
  104         { .vendor_id = NTB_HW_HYGON_VENDOR_ID,
  105           .device_id = NTB_HW_HYGON_DEVICE_ID1,
  106           .mw_count = 3,
  107           .bar_start_idx = 1,
  108           .spad_count = 16,
  109           .db_count = 16,
  110           .msix_vector_count = 24,
  111           .quirks = QUIRK_MW0_32BIT,
  112           .desc = "Hygon Non-Transparent Bridge"},
  113 };
  114 
  115 static const struct pci_device_table amd_ntb_devs[] = {
  116         { PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID1),
  117           .driver_data = (uintptr_t)&amd_ntb_hw_info_list[0],
  118           PCI_DESCR("AMD Non-Transparent Bridge") },
  119         { PCI_DEV(NTB_HW_AMD_VENDOR_ID, NTB_HW_AMD_DEVICE_ID2),
  120           .driver_data = (uintptr_t)&amd_ntb_hw_info_list[1],
  121           PCI_DESCR("AMD Non-Transparent Bridge") },
  122         { PCI_DEV(NTB_HW_HYGON_VENDOR_ID, NTB_HW_HYGON_DEVICE_ID1),
  123           .driver_data = (uintptr_t)&amd_ntb_hw_info_list[0],
  124           PCI_DESCR("Hygon Non-Transparent Bridge") }
  125 };
  126 
  127 static unsigned g_amd_ntb_hw_debug_level;
  128 SYSCTL_UINT(_hw_ntb, OID_AUTO, debug_level, CTLFLAG_RWTUN,
  129     &g_amd_ntb_hw_debug_level, 0, "amd_ntb_hw log level -- higher is verbose");
  130 
  131 #define amd_ntb_printf(lvl, ...) do {                           \
  132         if (lvl <= g_amd_ntb_hw_debug_level)                    \
  133                 device_printf(ntb->device, __VA_ARGS__);        \
  134 } while (0)
  135 
  136 #ifdef __i386__
  137 static __inline uint64_t
  138 bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
  139     bus_size_t offset)
  140 {
  141 
  142         return (bus_space_read_4(tag, handle, offset) |
  143             ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32);
  144 }
  145 
  146 static __inline void
  147 bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle,
  148     bus_size_t offset, uint64_t val)
  149 {
  150 
  151         bus_space_write_4(tag, handle, offset, val);
  152         bus_space_write_4(tag, handle, offset + 4, val >> 32);
  153 }
  154 #endif
  155 
  156 /*
  157  * AMD NTB INTERFACE ROUTINES
  158  */
  159 static int
  160 amd_ntb_port_number(device_t dev)
  161 {
  162         struct amd_ntb_softc *ntb = device_get_softc(dev);
  163 
  164         amd_ntb_printf(1, "%s: conn_type %d\n", __func__, ntb->conn_type);
  165 
  166         switch (ntb->conn_type) {
  167         case NTB_CONN_PRI:
  168                 return (NTB_PORT_PRI_USD);
  169         case NTB_CONN_SEC:
  170                 return (NTB_PORT_SEC_DSD);
  171         default:
  172                 break;
  173         }
  174 
  175         return (-EINVAL);
  176 }
  177 
  178 static int
  179 amd_ntb_peer_port_count(device_t dev)
  180 {
  181         struct amd_ntb_softc *ntb = device_get_softc(dev);
  182 
  183         amd_ntb_printf(1, "%s: peer cnt %d\n", __func__, NTB_DEF_PEER_CNT);
  184         return (NTB_DEF_PEER_CNT);
  185 }
  186 
  187 static int
  188 amd_ntb_peer_port_number(device_t dev, int pidx)
  189 {
  190         struct amd_ntb_softc *ntb = device_get_softc(dev);
  191 
  192         amd_ntb_printf(1, "%s: pidx %d conn type %d\n",
  193             __func__, pidx, ntb->conn_type);
  194 
  195         if (pidx != NTB_DEF_PEER_IDX)
  196                 return (-EINVAL);
  197 
  198         switch (ntb->conn_type) {
  199         case NTB_CONN_PRI:
  200                 return (NTB_PORT_SEC_DSD);
  201         case NTB_CONN_SEC:
  202                 return (NTB_PORT_PRI_USD);
  203         default:
  204                 break;
  205         }
  206 
  207         return (-EINVAL);
  208 }
  209 
  210 static int
  211 amd_ntb_peer_port_idx(device_t dev, int port)
  212 {
  213         struct amd_ntb_softc *ntb = device_get_softc(dev);
  214         int peer_port;
  215 
  216         peer_port = amd_ntb_peer_port_number(dev, NTB_DEF_PEER_IDX);
  217 
  218         amd_ntb_printf(1, "%s: port %d peer_port %d\n",
  219             __func__, port, peer_port);
  220 
  221         if (peer_port == -EINVAL || port != peer_port)
  222                 return (-EINVAL);
  223 
  224         return (0);
  225 }
  226 
  227 /*
  228  * AMD NTB INTERFACE - LINK ROUTINES
  229  */
  230 static inline int
  231 amd_link_is_up(struct amd_ntb_softc *ntb)
  232 {
  233 
  234         amd_ntb_printf(2, "%s: peer_sta 0x%x cntl_sta 0x%x\n",
  235             __func__, ntb->peer_sta, ntb->cntl_sta);
  236 
  237         if (!ntb->peer_sta)
  238                 return (NTB_LNK_STA_ACTIVE(ntb->cntl_sta));
  239 
  240         return (0);
  241 }
  242 
  243 static inline enum ntb_speed
  244 amd_ntb_link_sta_speed(struct amd_ntb_softc *ntb)
  245 {
  246 
  247         if (!amd_link_is_up(ntb))
  248                 return (NTB_SPEED_NONE);
  249 
  250         return (NTB_LNK_STA_SPEED(ntb->lnk_sta));
  251 }
  252 
  253 static inline enum ntb_width
  254 amd_ntb_link_sta_width(struct amd_ntb_softc *ntb)
  255 {
  256 
  257         if (!amd_link_is_up(ntb))
  258                 return (NTB_WIDTH_NONE);
  259 
  260         return (NTB_LNK_STA_WIDTH(ntb->lnk_sta));
  261 }
  262 
  263 static bool
  264 amd_ntb_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width)
  265 {
  266         struct amd_ntb_softc *ntb = device_get_softc(dev);
  267 
  268         if (speed != NULL)
  269                 *speed = amd_ntb_link_sta_speed(ntb);
  270         if (width != NULL)
  271                 *width = amd_ntb_link_sta_width(ntb);
  272 
  273         return (amd_link_is_up(ntb));
  274 }
  275 
  276 static int
  277 amd_ntb_link_enable(device_t dev, enum ntb_speed max_speed,
  278     enum ntb_width max_width)
  279 {
  280         struct amd_ntb_softc *ntb = device_get_softc(dev);
  281         uint32_t ntb_ctl;
  282 
  283         amd_ntb_printf(1, "%s: int_mask 0x%x conn_type %d\n",
  284             __func__, ntb->int_mask, ntb->conn_type);
  285 
  286         amd_init_side_info(ntb);
  287 
  288         /* Enable event interrupt */
  289         ntb->int_mask &= ~AMD_EVENT_INTMASK;
  290         amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
  291 
  292         if (ntb->conn_type == NTB_CONN_SEC)
  293                 return (EINVAL);
  294 
  295         amd_ntb_printf(0, "%s: Enabling Link.\n", __func__);
  296 
  297         ntb_ctl = amd_ntb_reg_read(4, AMD_CNTL_OFFSET);
  298         ntb_ctl |= (PMM_REG_CTL | SMM_REG_CTL);
  299         amd_ntb_printf(1, "%s: ntb_ctl 0x%x\n", __func__, ntb_ctl);
  300         amd_ntb_reg_write(4, AMD_CNTL_OFFSET, ntb_ctl);
  301 
  302         return (0);
  303 }
  304 
  305 static int
  306 amd_ntb_link_disable(device_t dev)
  307 {
  308         struct amd_ntb_softc *ntb = device_get_softc(dev);
  309         uint32_t ntb_ctl;
  310 
  311         amd_ntb_printf(1, "%s: int_mask 0x%x conn_type %d\n",
  312             __func__, ntb->int_mask, ntb->conn_type);
  313 
  314         amd_deinit_side_info(ntb);
  315 
  316         /* Disable event interrupt */
  317         ntb->int_mask |= AMD_EVENT_INTMASK;
  318         amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
  319 
  320         if (ntb->conn_type == NTB_CONN_SEC)
  321                 return (EINVAL);
  322 
  323         amd_ntb_printf(0, "%s: Disabling Link.\n", __func__);
  324 
  325         ntb_ctl = amd_ntb_reg_read(4, AMD_CNTL_OFFSET);
  326         ntb_ctl &= ~(PMM_REG_CTL | SMM_REG_CTL);
  327         amd_ntb_printf(1, "%s: ntb_ctl 0x%x\n", __func__, ntb_ctl);
  328         amd_ntb_reg_write(4, AMD_CNTL_OFFSET, ntb_ctl);
  329 
  330         return (0);
  331 }
  332 
  333 /*
  334  * AMD NTB memory window routines
  335  */
  336 static uint8_t
  337 amd_ntb_mw_count(device_t dev)
  338 {
  339         struct amd_ntb_softc *ntb = device_get_softc(dev);
  340 
  341         return (ntb->hw_info->mw_count);
  342 }
  343 
  344 static int
  345 amd_ntb_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base,
  346     caddr_t *vbase, size_t *size, size_t *align, size_t *align_size,
  347     bus_addr_t *plimit)
  348 {
  349         struct amd_ntb_softc *ntb = device_get_softc(dev);
  350         struct amd_ntb_pci_bar_info *bar_info;
  351 
  352         if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
  353                 return (EINVAL);
  354 
  355         bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
  356 
  357         if (base != NULL)
  358                 *base = bar_info->pbase;
  359 
  360         if (vbase != NULL)
  361                 *vbase = bar_info->vbase;
  362 
  363         if (align != NULL)
  364                 *align = bar_info->size;
  365 
  366         if (size != NULL)
  367                 *size = bar_info->size;
  368 
  369         if (align_size != NULL)
  370                 *align_size = 1;
  371 
  372         if (plimit != NULL) {
  373                 /*
  374                  * For Device ID 0x145B (which has 3 memory windows),
  375                  * memory window 0 use a 32-bit bar. The remaining
  376                  * cases all use 64-bit bar.
  377                  */
  378                 if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT))
  379                         *plimit = BUS_SPACE_MAXADDR_32BIT;
  380                 else
  381                         *plimit = BUS_SPACE_MAXADDR;
  382         }
  383 
  384         return (0);
  385 }
  386 
  387 static int
  388 amd_ntb_mw_set_trans(device_t dev, unsigned mw_idx, bus_addr_t addr, size_t size)
  389 {
  390         struct amd_ntb_softc *ntb = device_get_softc(dev);
  391         struct amd_ntb_pci_bar_info *bar_info;
  392 
  393         if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
  394                 return (EINVAL);
  395 
  396         bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
  397 
  398         /* Make sure the range fits in the usable mw size. */
  399         if (size > bar_info->size) {
  400                 amd_ntb_printf(0, "%s: size 0x%jx greater than mw_size 0x%jx\n",
  401                     __func__, (uintmax_t)size, (uintmax_t)bar_info->size);
  402                 return (EINVAL);
  403         }
  404 
  405         amd_ntb_printf(1, "%s: mw %d mw_size 0x%jx size 0x%jx base %p\n",
  406             __func__, mw_idx, (uintmax_t)bar_info->size,
  407             (uintmax_t)size, (void *)bar_info->pci_bus_handle);
  408 
  409         /*
  410          * AMD NTB XLAT and Limit registers needs to be written only after
  411          * link enable.
  412          *
  413          * Set and verify setting the translation address register.
  414          */
  415         amd_ntb_peer_reg_write(8, bar_info->xlat_off, (uint64_t)addr);
  416         amd_ntb_printf(0, "%s: mw %d xlat_off 0x%x cur_val 0x%jx addr %p\n",
  417             __func__, mw_idx, bar_info->xlat_off,
  418             amd_ntb_peer_reg_read(8, bar_info->xlat_off), (void *)addr);
  419 
  420         /*
  421          * Set and verify setting the limit register.
  422          *
  423          * For Device ID 0x145B (which has 3 memory windows),
  424          * memory window 0 use a 32-bit bar. The remaining
  425          * cases all use 64-bit bar.
  426          */
  427         if ((mw_idx == 0) && (ntb->hw_info->quirks & QUIRK_MW0_32BIT)) {
  428                 amd_ntb_reg_write(4, bar_info->limit_off, (uint32_t)size);
  429                 amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%x limit 0x%x\n",
  430                     __func__, bar_info->limit_off,
  431                     amd_ntb_peer_reg_read(4, bar_info->limit_off),
  432                     (uint32_t)size);
  433         } else {
  434                 amd_ntb_reg_write(8, bar_info->limit_off, (uint64_t)size);
  435                 amd_ntb_printf(1, "%s: limit_off 0x%x cur_val 0x%jx limit 0x%jx\n",
  436                     __func__, bar_info->limit_off,
  437                     amd_ntb_peer_reg_read(8, bar_info->limit_off),
  438                     (uintmax_t)size);
  439         }
  440 
  441         return (0);
  442 }
  443 
  444 static int
  445 amd_ntb_mw_clear_trans(device_t dev, unsigned mw_idx)
  446 {
  447         struct amd_ntb_softc *ntb = device_get_softc(dev);
  448 
  449         amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx);
  450 
  451         if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
  452                 return (EINVAL);
  453 
  454         return (amd_ntb_mw_set_trans(dev, mw_idx, 0, 0));
  455 }
  456 
  457 static int
  458 amd_ntb_mw_set_wc(device_t dev, unsigned int mw_idx, vm_memattr_t mode)
  459 {
  460         struct amd_ntb_softc *ntb = device_get_softc(dev);
  461         struct amd_ntb_pci_bar_info *bar_info;
  462         int rc;
  463 
  464         if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
  465                 return (EINVAL);
  466 
  467         bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
  468         if (mode == bar_info->map_mode)
  469                 return (0);
  470 
  471         rc = pmap_change_attr((vm_offset_t)bar_info->vbase, bar_info->size, mode);
  472         if (rc == 0)
  473                 bar_info->map_mode = mode;
  474 
  475         return (rc);
  476 }
  477 
  478 static int
  479 amd_ntb_mw_get_wc(device_t dev, unsigned mw_idx, vm_memattr_t *mode)
  480 {
  481         struct amd_ntb_softc *ntb = device_get_softc(dev);
  482         struct amd_ntb_pci_bar_info *bar_info;
  483 
  484         amd_ntb_printf(1, "%s: mw_idx %d\n", __func__, mw_idx);
  485 
  486         if (mw_idx < 0 || mw_idx >= ntb->hw_info->mw_count)
  487                 return (EINVAL);
  488 
  489         bar_info = &ntb->bar_info[ntb->hw_info->bar_start_idx + mw_idx];
  490         *mode = bar_info->map_mode;
  491 
  492         return (0);
  493 }
  494 
  495 /*
  496  * AMD NTB doorbell routines
  497  */
  498 static int
  499 amd_ntb_db_vector_count(device_t dev)
  500 {
  501         struct amd_ntb_softc *ntb = device_get_softc(dev);
  502 
  503         amd_ntb_printf(1, "%s: db_count 0x%x\n", __func__,
  504             ntb->hw_info->db_count);
  505 
  506         return (ntb->hw_info->db_count);
  507 }
  508 
  509 static uint64_t
  510 amd_ntb_db_valid_mask(device_t dev)
  511 {
  512         struct amd_ntb_softc *ntb = device_get_softc(dev);
  513 
  514         amd_ntb_printf(1, "%s: db_valid_mask 0x%x\n",
  515             __func__, ntb->db_valid_mask);
  516 
  517         return (ntb->db_valid_mask);
  518 }
  519 
  520 static uint64_t
  521 amd_ntb_db_vector_mask(device_t dev, uint32_t vector)
  522 {
  523         struct amd_ntb_softc *ntb = device_get_softc(dev);
  524 
  525         amd_ntb_printf(1, "%s: vector %d db_count 0x%x db_valid_mask 0x%x\n",
  526             __func__, vector, ntb->hw_info->db_count, ntb->db_valid_mask);
  527 
  528         if (vector < 0 || vector >= ntb->hw_info->db_count)
  529                 return (0);
  530 
  531         return (ntb->db_valid_mask & (1 << vector));
  532 }
  533 
  534 static uint64_t
  535 amd_ntb_db_read(device_t dev)
  536 {
  537         struct amd_ntb_softc *ntb = device_get_softc(dev);
  538         uint64_t dbstat_off;
  539 
  540         dbstat_off = (uint64_t)amd_ntb_reg_read(2, AMD_DBSTAT_OFFSET);
  541 
  542         amd_ntb_printf(1, "%s: dbstat_off 0x%jx\n", __func__, dbstat_off);
  543 
  544         return (dbstat_off);
  545 }
  546 
  547 static void
  548 amd_ntb_db_clear(device_t dev, uint64_t db_bits)
  549 {
  550         struct amd_ntb_softc *ntb = device_get_softc(dev);
  551 
  552         amd_ntb_printf(1, "%s: db_bits 0x%jx\n", __func__, db_bits);
  553         amd_ntb_reg_write(2, AMD_DBSTAT_OFFSET, (uint16_t)db_bits);
  554 }
  555 
  556 static void
  557 amd_ntb_db_set_mask(device_t dev, uint64_t db_bits)
  558 {
  559         struct amd_ntb_softc *ntb = device_get_softc(dev);
  560 
  561         DB_MASK_LOCK(ntb);
  562         amd_ntb_printf(1, "%s: db_mask 0x%x db_bits 0x%jx\n",
  563             __func__, ntb->db_mask, db_bits);
  564 
  565         ntb->db_mask |= db_bits;
  566         amd_ntb_reg_write(2, AMD_DBMASK_OFFSET, ntb->db_mask);
  567         DB_MASK_UNLOCK(ntb);
  568 }
  569 
  570 static void
  571 amd_ntb_db_clear_mask(device_t dev, uint64_t db_bits)
  572 {
  573         struct amd_ntb_softc *ntb = device_get_softc(dev);
  574 
  575         DB_MASK_LOCK(ntb);
  576         amd_ntb_printf(1, "%s: db_mask 0x%x db_bits 0x%jx\n",
  577             __func__, ntb->db_mask, db_bits);
  578 
  579         ntb->db_mask &= ~db_bits;
  580         amd_ntb_reg_write(2, AMD_DBMASK_OFFSET, ntb->db_mask);
  581         DB_MASK_UNLOCK(ntb);
  582 }
  583 
  584 static void
  585 amd_ntb_peer_db_set(device_t dev, uint64_t db_bits)
  586 {
  587         struct amd_ntb_softc *ntb = device_get_softc(dev);
  588 
  589         amd_ntb_printf(1, "%s: db_bits 0x%jx\n", __func__, db_bits);
  590         amd_ntb_reg_write(2, AMD_DBREQ_OFFSET, (uint16_t)db_bits);
  591 }
  592 
  593 /*
  594  * AMD NTB scratchpad routines
  595  */
  596 static uint8_t
  597 amd_ntb_spad_count(device_t dev)
  598 {
  599         struct amd_ntb_softc *ntb = device_get_softc(dev);
  600 
  601         amd_ntb_printf(1, "%s: spad_count 0x%x\n", __func__,
  602             ntb->spad_count);
  603 
  604         return (ntb->spad_count);
  605 }
  606 
  607 static int
  608 amd_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val)
  609 {
  610         struct amd_ntb_softc *ntb = device_get_softc(dev);
  611         uint32_t offset;
  612 
  613         amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
  614 
  615         if (idx < 0 || idx >= ntb->spad_count)
  616                 return (EINVAL);
  617 
  618         offset = ntb->self_spad + (idx << 2);
  619         *val = amd_ntb_reg_read(4, AMD_SPAD_OFFSET + offset);
  620         amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, *val);
  621 
  622         return (0);
  623 }
  624 
  625 static int
  626 amd_ntb_spad_write(device_t dev, unsigned int idx, uint32_t val)
  627 {
  628         struct amd_ntb_softc *ntb = device_get_softc(dev);
  629         uint32_t offset;
  630 
  631         amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
  632 
  633         if (idx < 0 || idx >= ntb->spad_count)
  634                 return (EINVAL);
  635 
  636         offset = ntb->self_spad + (idx << 2);
  637         amd_ntb_reg_write(4, AMD_SPAD_OFFSET + offset, val);
  638         amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, val);
  639 
  640         return (0);
  641 }
  642 
  643 static void
  644 amd_ntb_spad_clear(struct amd_ntb_softc *ntb)
  645 {
  646         uint8_t i;
  647 
  648         for (i = 0; i < ntb->spad_count; i++)
  649                 amd_ntb_spad_write(ntb->device, i, 0);
  650 }
  651 
  652 static int
  653 amd_ntb_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val)
  654 {
  655         struct amd_ntb_softc *ntb = device_get_softc(dev);
  656         uint32_t offset;
  657 
  658         amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
  659 
  660         if (idx < 0 || idx >= ntb->spad_count)
  661                 return (EINVAL);
  662 
  663         offset = ntb->peer_spad + (idx << 2);
  664         *val = amd_ntb_reg_read(4, AMD_SPAD_OFFSET + offset);
  665         amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, *val);
  666 
  667         return (0);
  668 }
  669 
  670 static int
  671 amd_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val)
  672 {
  673         struct amd_ntb_softc *ntb = device_get_softc(dev);
  674         uint32_t offset;
  675 
  676         amd_ntb_printf(2, "%s: idx %d\n", __func__, idx);
  677 
  678         if (idx < 0 || idx >= ntb->spad_count)
  679                 return (EINVAL);
  680 
  681         offset = ntb->peer_spad + (idx << 2);
  682         amd_ntb_reg_write(4, AMD_SPAD_OFFSET + offset, val);
  683         amd_ntb_printf(2, "%s: offset 0x%x val 0x%x\n", __func__, offset, val);
  684 
  685         return (0);
  686 }
  687 
  688 /*
  689  * AMD NTB INIT
  690  */
  691 static int
  692 amd_ntb_hw_info_handler(SYSCTL_HANDLER_ARGS)
  693 {
  694         struct amd_ntb_softc* ntb = arg1;
  695         struct sbuf *sb;
  696         int rc = 0;
  697 
  698         sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
  699         if (sb == NULL)
  700                 return (sb->s_error);
  701 
  702         sbuf_printf(sb, "NTB AMD Hardware info:\n\n");
  703         sbuf_printf(sb, "AMD NTB side: %s\n",
  704             (ntb->conn_type == NTB_CONN_PRI)? "PRIMARY" : "SECONDARY");
  705         sbuf_printf(sb, "AMD LNK STA: 0x%#06x\n", ntb->lnk_sta);
  706 
  707         if (!amd_link_is_up(ntb))
  708                 sbuf_printf(sb, "AMD Link Status: Down\n");
  709         else {
  710                 sbuf_printf(sb, "AMD Link Status: Up\n");
  711                 sbuf_printf(sb, "AMD Link Speed: PCI-E Gen %u\n",
  712                     NTB_LNK_STA_SPEED(ntb->lnk_sta));
  713                 sbuf_printf(sb, "AMD Link Width: PCI-E Width %u\n",
  714                     NTB_LNK_STA_WIDTH(ntb->lnk_sta));
  715         }
  716 
  717         sbuf_printf(sb, "AMD Memory window count: %d\n",
  718             ntb->hw_info->mw_count);
  719         sbuf_printf(sb, "AMD Spad count: %d\n",
  720             ntb->spad_count);
  721         sbuf_printf(sb, "AMD Doorbell count: %d\n",
  722             ntb->hw_info->db_count);
  723         sbuf_printf(sb, "AMD MSI-X vec count: %d\n\n",
  724             ntb->msix_vec_count);
  725         sbuf_printf(sb, "AMD Doorbell valid mask: 0x%x\n",
  726             ntb->db_valid_mask);
  727         sbuf_printf(sb, "AMD Doorbell Mask: 0x%x\n",
  728             amd_ntb_reg_read(4, AMD_DBMASK_OFFSET));
  729         sbuf_printf(sb, "AMD Doorbell: 0x%x\n",
  730             amd_ntb_reg_read(4, AMD_DBSTAT_OFFSET));
  731         sbuf_printf(sb, "AMD NTB Incoming XLAT: \n");
  732         sbuf_printf(sb, "AMD XLAT1: 0x%jx\n",
  733             amd_ntb_peer_reg_read(8, AMD_BAR1XLAT_OFFSET));
  734         sbuf_printf(sb, "AMD XLAT23: 0x%jx\n",
  735             amd_ntb_peer_reg_read(8, AMD_BAR23XLAT_OFFSET));
  736         sbuf_printf(sb, "AMD XLAT45: 0x%jx\n",
  737             amd_ntb_peer_reg_read(8, AMD_BAR45XLAT_OFFSET));
  738         sbuf_printf(sb, "AMD LMT1: 0x%x\n",
  739             amd_ntb_reg_read(4, AMD_BAR1LMT_OFFSET));
  740         sbuf_printf(sb, "AMD LMT23: 0x%jx\n",
  741             amd_ntb_reg_read(8, AMD_BAR23LMT_OFFSET));
  742         sbuf_printf(sb, "AMD LMT45: 0x%jx\n",
  743             amd_ntb_reg_read(8, AMD_BAR45LMT_OFFSET));
  744 
  745         rc = sbuf_finish(sb);
  746         sbuf_delete(sb);
  747         return (rc);
  748 }
  749 
  750 static void
  751 amd_ntb_sysctl_init(struct amd_ntb_softc *ntb)
  752 {
  753         struct sysctl_oid_list *globals;
  754         struct sysctl_ctx_list *ctx;
  755 
  756         ctx = device_get_sysctl_ctx(ntb->device);
  757         globals = SYSCTL_CHILDREN(device_get_sysctl_tree(ntb->device));
  758 
  759         SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "info",
  760             CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, ntb, 0,
  761             amd_ntb_hw_info_handler, "A", "AMD NTB HW Information");
  762 }
  763 
  764 /*
  765  * Polls the HW link status register(s); returns true if something has changed.
  766  */
  767 static bool
  768 amd_ntb_poll_link(struct amd_ntb_softc *ntb)
  769 {
  770         uint32_t fullreg, reg, stat;
  771 
  772         fullreg = amd_ntb_peer_reg_read(4, AMD_SIDEINFO_OFFSET);
  773         reg = fullreg & NTB_LIN_STA_ACTIVE_BIT;
  774 
  775         if (reg == ntb->cntl_sta)
  776                 return (false);
  777 
  778         amd_ntb_printf(0, "%s: SIDEINFO reg_val = 0x%x cntl_sta 0x%x\n",
  779             __func__, fullreg, ntb->cntl_sta);
  780 
  781         ntb->cntl_sta = reg;
  782 
  783         stat = pci_read_config(ntb->device, AMD_LINK_STATUS_OFFSET, 4);
  784 
  785         amd_ntb_printf(0, "%s: LINK_STATUS stat = 0x%x lnk_sta 0x%x.\n",
  786             __func__, stat, ntb->lnk_sta);
  787 
  788         ntb->lnk_sta = stat;
  789 
  790         return (true);
  791 }
  792 
  793 static void
  794 amd_link_hb(void *arg)
  795 {
  796         struct amd_ntb_softc *ntb = arg;
  797 
  798         if (amd_ntb_poll_link(ntb))
  799                 ntb_link_event(ntb->device);
  800 
  801         if (!amd_link_is_up(ntb)) {
  802                 callout_reset(&ntb->hb_timer, AMD_LINK_HB_TIMEOUT,
  803                     amd_link_hb, ntb);
  804         } else {
  805                 callout_reset(&ntb->hb_timer, (AMD_LINK_HB_TIMEOUT * 10),
  806                     amd_link_hb, ntb);
  807         }
  808 }
  809 
  810 static void
  811 amd_ntb_interrupt(struct amd_ntb_softc *ntb, uint16_t vec)
  812 {
  813         if (vec < ntb->hw_info->db_count)
  814                 ntb_db_event(ntb->device, vec);
  815         else
  816                 amd_ntb_printf(0, "Invalid vector %d\n", vec);
  817 }
  818 
  819 static void
  820 amd_ntb_vec_isr(void *arg)
  821 {
  822         struct amd_ntb_vec *nvec = arg;
  823 
  824         amd_ntb_interrupt(nvec->ntb, nvec->num);
  825 }
  826 
  827 static void
  828 amd_ntb_irq_isr(void *arg)
  829 {
  830         /* If we couldn't set up MSI-X, we only have the one vector. */
  831         amd_ntb_interrupt(arg, 0);
  832 }
  833 
  834 static void
  835 amd_init_side_info(struct amd_ntb_softc *ntb)
  836 {
  837         unsigned int reg;
  838 
  839         reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
  840         if (!(reg & AMD_SIDE_READY)) {
  841                 reg |= AMD_SIDE_READY;
  842                 amd_ntb_reg_write(4, AMD_SIDEINFO_OFFSET, reg);
  843         }
  844         reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
  845 }
  846 
  847 static void
  848 amd_deinit_side_info(struct amd_ntb_softc *ntb)
  849 {
  850         unsigned int reg;
  851 
  852         reg = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
  853         if (reg & AMD_SIDE_READY) {
  854                 reg &= ~AMD_SIDE_READY;
  855                 amd_ntb_reg_write(4, AMD_SIDEINFO_OFFSET, reg);
  856                 amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
  857         }
  858 }
  859 
  860 static int
  861 amd_ntb_setup_isr(struct amd_ntb_softc *ntb, uint16_t num_vectors, bool msi,
  862     bool intx)
  863 {
  864         uint16_t i;
  865         int flags = 0, rc = 0;
  866 
  867         flags |= RF_ACTIVE;
  868         if (intx)
  869                 flags |= RF_SHAREABLE;
  870 
  871         for (i = 0; i < num_vectors; i++) {
  872                 /* RID should be 0 for intx */
  873                 if (intx)
  874                         ntb->int_info[i].rid = i;
  875                 else
  876                         ntb->int_info[i].rid = i + 1;
  877 
  878                 ntb->int_info[i].res = bus_alloc_resource_any(ntb->device,
  879                     SYS_RES_IRQ, &ntb->int_info[i].rid, flags);
  880                 if (ntb->int_info[i].res == NULL) {
  881                         amd_ntb_printf(0, "bus_alloc_resource IRQ failed\n");
  882                         return (ENOMEM);
  883                 }
  884 
  885                 ntb->int_info[i].tag = NULL;
  886                 ntb->allocated_interrupts++;
  887 
  888                 if (msi || intx) {
  889                         rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
  890                             INTR_MPSAFE | INTR_TYPE_MISC, NULL, amd_ntb_irq_isr,
  891                             ntb, &ntb->int_info[i].tag);
  892                 } else {
  893                         rc = bus_setup_intr(ntb->device, ntb->int_info[i].res,
  894                             INTR_MPSAFE | INTR_TYPE_MISC, NULL, amd_ntb_vec_isr,
  895                             &ntb->msix_vec[i], &ntb->int_info[i].tag);
  896                 }
  897 
  898                 if (rc != 0) {
  899                         amd_ntb_printf(0, "bus_setup_intr %d failed\n", i);
  900                         return (ENXIO);
  901                 }
  902         }
  903 
  904         return (0);
  905 }
  906 
  907 static int
  908 amd_ntb_create_msix_vec(struct amd_ntb_softc *ntb, uint32_t max_vectors)
  909 {
  910         uint8_t i;
  911 
  912         ntb->msix_vec = malloc(max_vectors * sizeof(*ntb->msix_vec), M_AMD_NTB,
  913             M_ZERO | M_WAITOK);
  914 
  915         for (i = 0; i < max_vectors; i++) {
  916                 ntb->msix_vec[i].num = i;
  917                 ntb->msix_vec[i].ntb = ntb;
  918         }
  919 
  920         return (0);
  921 }
  922 
  923 static void
  924 amd_ntb_free_msix_vec(struct amd_ntb_softc *ntb)
  925 {
  926         if (ntb->msix_vec_count) {
  927                 pci_release_msi(ntb->device);
  928                 ntb->msix_vec_count = 0;
  929         }
  930 
  931         if (ntb->msix_vec != NULL) {
  932                 free(ntb->msix_vec, M_AMD_NTB);
  933                 ntb->msix_vec = NULL;
  934         }
  935 }
  936 
  937 static int
  938 amd_ntb_init_isr(struct amd_ntb_softc *ntb)
  939 {
  940         uint32_t supported_vectors, num_vectors;
  941         bool msi = false, intx = false;
  942         int rc = 0;
  943 
  944         ntb->db_mask = ntb->db_valid_mask;
  945 
  946         rc = amd_ntb_create_msix_vec(ntb, ntb->hw_info->msix_vector_count);
  947         if (rc != 0) {
  948                 amd_ntb_printf(0, "Error creating msix vectors: %d\n", rc);
  949                 return (ENOMEM);
  950         }
  951 
  952         /*
  953          * Check the number of MSI-X message supported by the device.
  954          * Minimum necessary MSI-X message count should be equal to db_count.
  955          */
  956         supported_vectors = pci_msix_count(ntb->device);
  957         num_vectors = MIN(supported_vectors, ntb->hw_info->db_count);
  958         if (num_vectors < ntb->hw_info->db_count) {
  959                 amd_ntb_printf(0, "No minimum msix: supported %d db %d\n",
  960                     supported_vectors, ntb->hw_info->db_count);
  961                 msi = true;
  962                 goto err_msix_enable;
  963         }
  964 
  965         /* Allocate the necessary number of MSI-x messages */
  966         rc = pci_alloc_msix(ntb->device, &num_vectors);
  967         if (rc != 0) {
  968                 amd_ntb_printf(0, "Error allocating msix vectors: %d\n", rc);
  969                 msi = true;
  970                 goto err_msix_enable;
  971         }
  972 
  973         if (num_vectors < ntb->hw_info->db_count) {
  974                 amd_ntb_printf(0, "Allocated only %d MSI-X\n", num_vectors);
  975                 msi = true;
  976                 /*
  977                  * Else set ntb->hw_info->db_count = ntb->msix_vec_count =
  978                  * num_vectors, msi=false and dont release msi.
  979                  */
  980         }
  981 
  982 err_msix_enable:
  983 
  984         if (msi) {
  985                 free(ntb->msix_vec, M_AMD_NTB);
  986                 ntb->msix_vec = NULL;
  987                 pci_release_msi(ntb->device);
  988                 num_vectors = 1;
  989                 rc = pci_alloc_msi(ntb->device, &num_vectors);
  990                 if (rc != 0) {
  991                         amd_ntb_printf(0, "Error allocating msix vectors: %d\n", rc);
  992                         msi = false;
  993                         intx = true;
  994                 }
  995         }
  996 
  997         ntb->hw_info->db_count = ntb->msix_vec_count = num_vectors;
  998 
  999         if (intx) {
 1000                 num_vectors = 1;
 1001                 ntb->hw_info->db_count = 1;
 1002                 ntb->msix_vec_count = 0;
 1003         }
 1004 
 1005         amd_ntb_printf(0, "%s: db %d msix %d msi %d intx %d\n",
 1006             __func__, ntb->hw_info->db_count, ntb->msix_vec_count, (int)msi, (int)intx);
 1007 
 1008         rc = amd_ntb_setup_isr(ntb, num_vectors, msi, intx);
 1009         if (rc != 0) {
 1010                 amd_ntb_printf(0, "Error setting up isr: %d\n", rc);
 1011                 amd_ntb_free_msix_vec(ntb);
 1012         }
 1013 
 1014         return (rc);
 1015 }
 1016 
 1017 static void
 1018 amd_ntb_deinit_isr(struct amd_ntb_softc *ntb)
 1019 {
 1020         struct amd_ntb_int_info *current_int;
 1021         int i;
 1022 
 1023         /* Mask all doorbell interrupts */
 1024         ntb->db_mask = ntb->db_valid_mask;
 1025         amd_ntb_reg_write(4, AMD_DBMASK_OFFSET, ntb->db_mask);
 1026 
 1027         for (i = 0; i < ntb->allocated_interrupts; i++) {
 1028                 current_int = &ntb->int_info[i];
 1029                 if (current_int->tag != NULL)
 1030                         bus_teardown_intr(ntb->device, current_int->res,
 1031                             current_int->tag);
 1032 
 1033                 if (current_int->res != NULL)
 1034                         bus_release_resource(ntb->device, SYS_RES_IRQ,
 1035                             rman_get_rid(current_int->res), current_int->res);
 1036         }
 1037 
 1038         amd_ntb_free_msix_vec(ntb);
 1039 }
 1040 
 1041 static enum amd_ntb_conn_type
 1042 amd_ntb_get_topo(struct amd_ntb_softc *ntb)
 1043 {
 1044         uint32_t info;
 1045 
 1046         info = amd_ntb_reg_read(4, AMD_SIDEINFO_OFFSET);
 1047 
 1048         if (info & AMD_SIDE_MASK)
 1049                 return (NTB_CONN_SEC);
 1050 
 1051         return (NTB_CONN_PRI);
 1052 }
 1053 
 1054 static int
 1055 amd_ntb_init_dev(struct amd_ntb_softc *ntb)
 1056 {
 1057         ntb->db_valid_mask       = (1ull << ntb->hw_info->db_count) - 1;
 1058         mtx_init(&ntb->db_mask_lock, "amd ntb db bits", NULL, MTX_SPIN);
 1059 
 1060         switch (ntb->conn_type) {
 1061         case NTB_CONN_PRI:
 1062         case NTB_CONN_SEC:
 1063                 ntb->spad_count >>= 1;
 1064 
 1065                 if (ntb->conn_type == NTB_CONN_PRI) {
 1066                         ntb->self_spad = 0;
 1067                         ntb->peer_spad = 0x20;
 1068                 } else {
 1069                         ntb->self_spad = 0x20;
 1070                         ntb->peer_spad = 0;
 1071                 }
 1072 
 1073                 callout_init(&ntb->hb_timer, 1);
 1074                 callout_reset(&ntb->hb_timer, AMD_LINK_HB_TIMEOUT,
 1075                     amd_link_hb, ntb);
 1076 
 1077                 break;
 1078 
 1079         default:
 1080                 amd_ntb_printf(0, "Unsupported AMD NTB topology %d\n",
 1081                     ntb->conn_type);
 1082                 return (EINVAL);
 1083         }
 1084 
 1085         ntb->int_mask = AMD_EVENT_INTMASK;
 1086         amd_ntb_reg_write(4, AMD_INTMASK_OFFSET, ntb->int_mask);
 1087 
 1088         return (0);
 1089 }
 1090 
 1091 static int
 1092 amd_ntb_init(struct amd_ntb_softc *ntb)
 1093 {
 1094         int rc = 0;
 1095 
 1096         ntb->conn_type = amd_ntb_get_topo(ntb);
 1097         amd_ntb_printf(0, "AMD NTB Side: %s\n",
 1098             (ntb->conn_type == NTB_CONN_PRI)? "PRIMARY" : "SECONDARY");
 1099 
 1100         rc = amd_ntb_init_dev(ntb);
 1101         if (rc != 0)
 1102                 return (rc);
 1103 
 1104         rc = amd_ntb_init_isr(ntb);
 1105         if (rc != 0)
 1106                 return (rc);
 1107 
 1108         return (0);
 1109 }
 1110 
 1111 static void
 1112 print_map_success(struct amd_ntb_softc *ntb, struct amd_ntb_pci_bar_info *bar,
 1113     const char *kind)
 1114 {
 1115         amd_ntb_printf(0, "Mapped BAR%d v:[%p-%p] p:[0x%jx-0x%jx] (0x%jx bytes) (%s)\n",
 1116             PCI_RID2BAR(bar->pci_resource_id), bar->vbase,
 1117             (char *)bar->vbase + bar->size - 1, (uintmax_t)bar->pbase,
 1118             (uintmax_t)(bar->pbase + bar->size - 1), (uintmax_t)bar->size, kind);
 1119 }
 1120 
 1121 static void
 1122 save_bar_parameters(struct amd_ntb_pci_bar_info *bar)
 1123 {
 1124         bar->pci_bus_tag = rman_get_bustag(bar->pci_resource);
 1125         bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource);
 1126         bar->pbase = rman_get_start(bar->pci_resource);
 1127         bar->size = rman_get_size(bar->pci_resource);
 1128         bar->vbase = rman_get_virtual(bar->pci_resource);
 1129         bar->map_mode = VM_MEMATTR_UNCACHEABLE;
 1130 }
 1131 
 1132 static int
 1133 map_bar(struct amd_ntb_softc *ntb, struct amd_ntb_pci_bar_info *bar)
 1134 {
 1135         bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY,
 1136             &bar->pci_resource_id, RF_ACTIVE);
 1137         if (bar->pci_resource == NULL)
 1138                 return (ENXIO);
 1139 
 1140         save_bar_parameters(bar);
 1141         print_map_success(ntb, bar, "mmr");
 1142 
 1143         return (0);
 1144 }
 1145 
 1146 static int
 1147 amd_ntb_map_pci_bars(struct amd_ntb_softc *ntb)
 1148 {
 1149         int rc = 0;
 1150 
 1151         /* NTB Config/Control registers - BAR 0 */
 1152         ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0);
 1153         rc = map_bar(ntb, &ntb->bar_info[NTB_CONFIG_BAR]);
 1154         if (rc != 0)
 1155                 goto out;
 1156 
 1157         /* Memory Window 0 BAR - BAR 1 */
 1158         ntb->bar_info[NTB_BAR_1].pci_resource_id = PCIR_BAR(1);
 1159         rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_1]);
 1160         if (rc != 0)
 1161                 goto out;
 1162         ntb->bar_info[NTB_BAR_1].xlat_off = AMD_BAR1XLAT_OFFSET;
 1163         ntb->bar_info[NTB_BAR_1].limit_off = AMD_BAR1LMT_OFFSET;
 1164 
 1165         /* Memory Window 1 BAR - BAR 2&3 */
 1166         ntb->bar_info[NTB_BAR_2].pci_resource_id = PCIR_BAR(2);
 1167         rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_2]);
 1168         if (rc != 0)
 1169                 goto out;
 1170         ntb->bar_info[NTB_BAR_2].xlat_off = AMD_BAR23XLAT_OFFSET;
 1171         ntb->bar_info[NTB_BAR_2].limit_off = AMD_BAR23LMT_OFFSET;
 1172 
 1173         /* Memory Window 2 BAR - BAR 4&5 */
 1174         ntb->bar_info[NTB_BAR_3].pci_resource_id = PCIR_BAR(4);
 1175         rc = map_bar(ntb, &ntb->bar_info[NTB_BAR_3]);
 1176         if (rc != 0)
 1177                 goto out;
 1178         ntb->bar_info[NTB_BAR_3].xlat_off = AMD_BAR45XLAT_OFFSET;
 1179         ntb->bar_info[NTB_BAR_3].limit_off = AMD_BAR45LMT_OFFSET;
 1180 
 1181 out:
 1182         if (rc != 0)
 1183                 amd_ntb_printf(0, "unable to allocate pci resource\n");
 1184 
 1185         return (rc);
 1186 }
 1187 
 1188 static void
 1189 amd_ntb_unmap_pci_bars(struct amd_ntb_softc *ntb)
 1190 {
 1191         struct amd_ntb_pci_bar_info *bar_info;
 1192         int i;
 1193 
 1194         for (i = 0; i < NTB_MAX_BARS; i++) {
 1195                 bar_info = &ntb->bar_info[i];
 1196                 if (bar_info->pci_resource != NULL)
 1197                         bus_release_resource(ntb->device, SYS_RES_MEMORY,
 1198                             bar_info->pci_resource_id, bar_info->pci_resource);
 1199         }
 1200 }
 1201 
 1202 static int
 1203 amd_ntb_probe(device_t device)
 1204 {
 1205         struct amd_ntb_softc *ntb = device_get_softc(device);
 1206         const struct pci_device_table *tbl;
 1207 
 1208         tbl = PCI_MATCH(device, amd_ntb_devs);
 1209         if (tbl == NULL)
 1210                 return (ENXIO);
 1211 
 1212         ntb->hw_info = (struct amd_ntb_hw_info *)tbl->driver_data;
 1213         ntb->spad_count = ntb->hw_info->spad_count;
 1214         device_set_desc(device, tbl->descr);
 1215 
 1216         return (BUS_PROBE_GENERIC);
 1217 }
 1218 
 1219 static int
 1220 amd_ntb_attach(device_t device)
 1221 {
 1222         struct amd_ntb_softc *ntb = device_get_softc(device);
 1223         int error;
 1224 
 1225         ntb->device = device;
 1226 
 1227         /* Enable PCI bus mastering for "device" */
 1228         pci_enable_busmaster(ntb->device);
 1229 
 1230         error = amd_ntb_map_pci_bars(ntb);
 1231         if (error)
 1232                 goto out;
 1233                 
 1234         error = amd_ntb_init(ntb);
 1235         if (error)
 1236                 goto out;
 1237 
 1238         amd_init_side_info(ntb);
 1239 
 1240         amd_ntb_spad_clear(ntb);
 1241 
 1242         amd_ntb_sysctl_init(ntb);
 1243 
 1244         /* Attach children to this controller */
 1245         error = ntb_register_device(device);
 1246 
 1247 out:
 1248         if (error)
 1249                 amd_ntb_detach(device);
 1250 
 1251         return (error);
 1252 }
 1253 
 1254 static int
 1255 amd_ntb_detach(device_t device)
 1256 {
 1257         struct amd_ntb_softc *ntb = device_get_softc(device);
 1258 
 1259         ntb_unregister_device(device);
 1260         amd_deinit_side_info(ntb);
 1261         callout_drain(&ntb->hb_timer);
 1262         amd_ntb_deinit_isr(ntb);
 1263         mtx_destroy(&ntb->db_mask_lock);
 1264         pci_disable_busmaster(ntb->device);
 1265         amd_ntb_unmap_pci_bars(ntb);
 1266 
 1267         return (0);
 1268 }
 1269 
 1270 static device_method_t ntb_amd_methods[] = {
 1271         /* Device interface */
 1272         DEVMETHOD(device_probe,         amd_ntb_probe),
 1273         DEVMETHOD(device_attach,        amd_ntb_attach),
 1274         DEVMETHOD(device_detach,        amd_ntb_detach),
 1275 
 1276         /* Bus interface */
 1277         DEVMETHOD(bus_child_location,   ntb_child_location),
 1278         DEVMETHOD(bus_print_child,      ntb_print_child),
 1279         DEVMETHOD(bus_get_dma_tag,      ntb_get_dma_tag),
 1280 
 1281         /* NTB interface */
 1282         DEVMETHOD(ntb_port_number,      amd_ntb_port_number),
 1283         DEVMETHOD(ntb_peer_port_count,  amd_ntb_peer_port_count),
 1284         DEVMETHOD(ntb_peer_port_number, amd_ntb_peer_port_number),
 1285         DEVMETHOD(ntb_peer_port_idx,    amd_ntb_peer_port_idx),
 1286         DEVMETHOD(ntb_link_is_up,       amd_ntb_link_is_up),
 1287         DEVMETHOD(ntb_link_enable,      amd_ntb_link_enable),
 1288         DEVMETHOD(ntb_link_disable,     amd_ntb_link_disable),
 1289         DEVMETHOD(ntb_mw_count,         amd_ntb_mw_count),
 1290         DEVMETHOD(ntb_mw_get_range,     amd_ntb_mw_get_range),
 1291         DEVMETHOD(ntb_mw_set_trans,     amd_ntb_mw_set_trans),
 1292         DEVMETHOD(ntb_mw_clear_trans,   amd_ntb_mw_clear_trans),
 1293         DEVMETHOD(ntb_mw_set_wc,        amd_ntb_mw_set_wc),
 1294         DEVMETHOD(ntb_mw_get_wc,        amd_ntb_mw_get_wc),
 1295         DEVMETHOD(ntb_db_valid_mask,    amd_ntb_db_valid_mask),
 1296         DEVMETHOD(ntb_db_vector_count,  amd_ntb_db_vector_count),
 1297         DEVMETHOD(ntb_db_vector_mask,   amd_ntb_db_vector_mask),
 1298         DEVMETHOD(ntb_db_read,          amd_ntb_db_read),
 1299         DEVMETHOD(ntb_db_clear,         amd_ntb_db_clear),
 1300         DEVMETHOD(ntb_db_set_mask,      amd_ntb_db_set_mask),
 1301         DEVMETHOD(ntb_db_clear_mask,    amd_ntb_db_clear_mask),
 1302         DEVMETHOD(ntb_peer_db_set,      amd_ntb_peer_db_set),
 1303         DEVMETHOD(ntb_spad_count,       amd_ntb_spad_count),
 1304         DEVMETHOD(ntb_spad_read,        amd_ntb_spad_read),
 1305         DEVMETHOD(ntb_spad_write,       amd_ntb_spad_write),
 1306         DEVMETHOD(ntb_peer_spad_read,   amd_ntb_peer_spad_read),
 1307         DEVMETHOD(ntb_peer_spad_write,  amd_ntb_peer_spad_write),
 1308         DEVMETHOD_END
 1309 };
 1310 
 1311 static DEFINE_CLASS_0(ntb_hw, ntb_amd_driver, ntb_amd_methods,
 1312     sizeof(struct amd_ntb_softc));
 1313 DRIVER_MODULE(ntb_hw_amd, pci, ntb_amd_driver, NULL, NULL);
 1314 MODULE_DEPEND(ntb_hw_amd, ntb, 1, 1, 1);
 1315 MODULE_VERSION(ntb_hw_amd, 1);
 1316 PCI_PNP_INFO(amd_ntb_devs);

Cache object: 714f7aa0fd898f361bb63be7a5ac8e1c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.