13434Sesaxe /*
23434Sesaxe * CDDL HEADER START
33434Sesaxe *
43434Sesaxe * The contents of this file are subject to the terms of the
53434Sesaxe * Common Development and Distribution License (the "License").
63434Sesaxe * You may not use this file except in compliance with the License.
73434Sesaxe *
83434Sesaxe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93434Sesaxe * or http://www.opensolaris.org/os/licensing.
103434Sesaxe * See the License for the specific language governing permissions
113434Sesaxe * and limitations under the License.
123434Sesaxe *
133434Sesaxe * When distributing Covered Code, include this CDDL HEADER in each
143434Sesaxe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153434Sesaxe * If applicable, add the following below this CDDL HEADER, with the
163434Sesaxe * fields enclosed by brackets "[]" replaced with your own identifying
173434Sesaxe * information: Portions Copyright [yyyy] [name of copyright owner]
183434Sesaxe *
193434Sesaxe * CDDL HEADER END
203434Sesaxe */
213434Sesaxe
223434Sesaxe /*
238906SEric.Saxe@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
243434Sesaxe * Use is subject to license terms.
253434Sesaxe */
263434Sesaxe
273434Sesaxe /*
283434Sesaxe * Display processor group information
293434Sesaxe */
303434Sesaxe
313434Sesaxe #include "pg.h"
323434Sesaxe
333434Sesaxe #include <mdb/mdb_modapi.h>
343434Sesaxe #include <sys/pghw.h>
358906SEric.Saxe@Sun.COM #include <sys/cmt.h>
363434Sesaxe
373434Sesaxe /*
383434Sesaxe * PG hardware types indexed by hardware ID
393434Sesaxe */
403434Sesaxe char *pg_hw_names[] = {
413434Sesaxe "hw",
423434Sesaxe "ipipe",
433434Sesaxe "cache",
443434Sesaxe "fpu",
455079Sjc25722 "mpipe",
465079Sjc25722 "chip",
473434Sesaxe "memory",
488906SEric.Saxe@Sun.COM "active_pwr",
498906SEric.Saxe@Sun.COM "idle_pwr",
503434Sesaxe };
513434Sesaxe
523434Sesaxe #define A_CNT(arr) (sizeof (arr) / sizeof (arr[0]))
533434Sesaxe
543434Sesaxe #define NHW A_CNT(pg_hw_names)
553434Sesaxe
563434Sesaxe /*
573434Sesaxe * Convert HW id to symbolic name
583434Sesaxe */
593434Sesaxe static char *
pg_hw_name(int hw)603434Sesaxe pg_hw_name(int hw)
613434Sesaxe {
623434Sesaxe return ((hw < 0 || hw > NHW) ? "UNKNOWN" : pg_hw_names[hw]);
633434Sesaxe }
643434Sesaxe
653434Sesaxe /*
663434Sesaxe * Display processor group.
673434Sesaxe */
683434Sesaxe /* ARGSUSED */
693434Sesaxe int
pg(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)703434Sesaxe pg(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
713434Sesaxe {
723434Sesaxe pg_t pg;
733434Sesaxe pghw_t pghw;
748906SEric.Saxe@Sun.COM pg_cmt_t pg_cmt;
753434Sesaxe pg_class_t pg_class;
763434Sesaxe int opt_q = 0; /* display only address. */
778906SEric.Saxe@Sun.COM int is_cmt = 0; /* This is CMT pg */
783434Sesaxe
793434Sesaxe /* Should provide an address */
803434Sesaxe if (! (flags & DCMD_ADDRSPEC))
813434Sesaxe return (DCMD_USAGE);
823434Sesaxe
833434Sesaxe if (mdb_getopts(argc, argv,
843434Sesaxe 'q', MDB_OPT_SETBITS, TRUE, &opt_q,
855079Sjc25722 NULL) != argc)
863434Sesaxe return (DCMD_USAGE);
873434Sesaxe
883434Sesaxe if (flags & DCMD_PIPE_OUT)
893434Sesaxe opt_q = B_TRUE;
903434Sesaxe
913434Sesaxe if (DCMD_HDRSPEC(flags) && !opt_q) {
928906SEric.Saxe@Sun.COM mdb_printf("%6s %?s %6s %7s %11s %5s %5s\n",
933434Sesaxe "PGID",
943434Sesaxe "ADDR",
953434Sesaxe "PHYSID",
963434Sesaxe "CLASS",
973434Sesaxe "HARDWARE",
988906SEric.Saxe@Sun.COM "#CPUs",
998906SEric.Saxe@Sun.COM "LOAD");
1003434Sesaxe }
1013434Sesaxe
1023434Sesaxe /*
1033434Sesaxe * Read pg at specified address
1043434Sesaxe */
1053434Sesaxe if (mdb_vread(&pg, sizeof (struct pg), addr) == -1) {
1063434Sesaxe mdb_warn("unable to read 'pg' at %p", addr);
1073434Sesaxe return (DCMD_ERR);
1083434Sesaxe }
1093434Sesaxe
1103434Sesaxe /*
1113434Sesaxe * In quiet mode just print pg address
1123434Sesaxe */
1133434Sesaxe if (opt_q) {
1143434Sesaxe mdb_printf("%0?p\n", addr);
1153434Sesaxe return (DCMD_OK);
1163434Sesaxe }
1173434Sesaxe
118*9892Srafael.vanoni@sun.com if (mdb_vread(&pg_class, sizeof (struct pg_class),
119*9892Srafael.vanoni@sun.com (uintptr_t)pg.pg_class) == -1) {
120*9892Srafael.vanoni@sun.com mdb_warn("unable to read 'pg_class' at %p", pg.pg_class);
121*9892Srafael.vanoni@sun.com return (DCMD_ERR);
122*9892Srafael.vanoni@sun.com }
123*9892Srafael.vanoni@sun.com
1248906SEric.Saxe@Sun.COM if (strcmp(pg_class.pgc_name, "cmt") == 0) {
1258906SEric.Saxe@Sun.COM if (mdb_vread(&pg_cmt, sizeof (pg_cmt_t), addr) == -1) {
1268906SEric.Saxe@Sun.COM mdb_warn("unable to read 'cmt pg' at %p", addr);
1278906SEric.Saxe@Sun.COM return (DCMD_ERR);
1288906SEric.Saxe@Sun.COM }
1298906SEric.Saxe@Sun.COM is_cmt = 1;
1308906SEric.Saxe@Sun.COM }
1318906SEric.Saxe@Sun.COM
1323434Sesaxe if (pg.pg_relation == PGR_PHYSICAL) {
1333434Sesaxe if (mdb_vread(&pghw, sizeof (struct pghw), addr) == -1) {
1343434Sesaxe mdb_warn("unable to read 'pghw' at %p", addr);
1353434Sesaxe return (DCMD_ERR);
1363434Sesaxe }
1373434Sesaxe /*
1383434Sesaxe * Display the physical PG info.
1393434Sesaxe */
1408906SEric.Saxe@Sun.COM mdb_printf("%6d %?p %6d %7s %11s %5d %5d\n",
1413434Sesaxe pg.pg_id, addr, pghw.pghw_instance,
1423434Sesaxe pg_class.pgc_name, pg_hw_name(pghw.pghw_hw),
1438906SEric.Saxe@Sun.COM pg.pg_cpus.grp_size,
1448906SEric.Saxe@Sun.COM is_cmt ? pg_cmt.cmt_utilization : 0);
1453434Sesaxe } else {
1463434Sesaxe /*
1473434Sesaxe * Display the basic PG info.
1483434Sesaxe */
1493434Sesaxe mdb_printf("%6d %?p %7s %5d\n",
1503434Sesaxe pg.pg_id, addr, pg_class.pgc_name,
1513434Sesaxe pg.pg_cpus.grp_size);
1523434Sesaxe }
1533434Sesaxe
1543434Sesaxe return (DCMD_OK);
1553434Sesaxe }
156