1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 */ 15 16 /* 17 * PCIe related dcmds 18 */ 19 20 #include <mdb/mdb_modapi.h> 21 #include <sys/dditypes.h> 22 #include <sys/ddi_impldefs.h> 23 #include <sys/pcie_impl.h> 24 25 boolean_t 26 pcie_bus_match(const struct dev_info *devi, uintptr_t *bus_p) 27 { 28 if (devi->devi_bus.port_up.info.port.type == DEVI_PORT_TYPE_PCI) { 29 *bus_p = (uintptr_t)devi->devi_bus.port_up.priv_p; 30 } else if (devi->devi_bus.port_down.info.port.type == 31 DEVI_PORT_TYPE_PCI) { 32 *bus_p = (uintptr_t)devi->devi_bus.port_down.priv_p; 33 } else { 34 return (B_FALSE); 35 } 36 37 return (B_TRUE); 38 } 39 40 int 41 pcie_bus_walk_init(mdb_walk_state_t *wsp) 42 { 43 if (wsp->walk_addr != 0) { 44 mdb_warn("pcie_bus walker doesn't support non-global walks\n"); 45 return (WALK_ERR); 46 } 47 48 if (mdb_layered_walk("devinfo", wsp) == -1) { 49 mdb_warn("couldn't walk \"devinfo\""); 50 return (WALK_ERR); 51 } 52 53 return (WALK_NEXT); 54 } 55 56 int 57 pcie_bus_walk_step(mdb_walk_state_t *wsp) 58 { 59 const struct dev_info *devi; 60 uintptr_t bus_addr; 61 struct pcie_bus bus; 62 63 if (wsp->walk_layer == NULL) { 64 mdb_warn("missing layered walk info\n"); 65 return (WALK_ERR); 66 } 67 68 devi = wsp->walk_layer; 69 if (!pcie_bus_match(devi, &bus_addr)) { 70 return (WALK_NEXT); 71 } 72 73 if (mdb_vread(&bus, sizeof (bus), bus_addr) == -1) { 74 mdb_warn("failed to read pcie_bus_t at %p", bus_addr); 75 return (WALK_NEXT); 76 } 77 78 return (wsp->walk_callback(bus_addr, &bus, wsp->walk_cbdata)); 79 } 80