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