1fb2f18f8Sesaxe /* 2fb2f18f8Sesaxe * CDDL HEADER START 3fb2f18f8Sesaxe * 4fb2f18f8Sesaxe * The contents of this file are subject to the terms of the 5fb2f18f8Sesaxe * Common Development and Distribution License (the "License"). 6fb2f18f8Sesaxe * You may not use this file except in compliance with the License. 7fb2f18f8Sesaxe * 8fb2f18f8Sesaxe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9fb2f18f8Sesaxe * or http://www.opensolaris.org/os/licensing. 10fb2f18f8Sesaxe * See the License for the specific language governing permissions 11fb2f18f8Sesaxe * and limitations under the License. 12fb2f18f8Sesaxe * 13fb2f18f8Sesaxe * When distributing Covered Code, include this CDDL HEADER in each 14fb2f18f8Sesaxe * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15fb2f18f8Sesaxe * If applicable, add the following below this CDDL HEADER, with the 16fb2f18f8Sesaxe * fields enclosed by brackets "[]" replaced with your own identifying 17fb2f18f8Sesaxe * information: Portions Copyright [yyyy] [name of copyright owner] 18fb2f18f8Sesaxe * 19fb2f18f8Sesaxe * CDDL HEADER END 20fb2f18f8Sesaxe */ 218031591dSSrihari Venkatesan 22fb2f18f8Sesaxe /* 23*d3c97224SAlexander Kolbasov * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24fb2f18f8Sesaxe */ 25fb2f18f8Sesaxe 26fb2f18f8Sesaxe #ifndef _PGHW_H 27fb2f18f8Sesaxe #define _PGHW_H 28fb2f18f8Sesaxe 29fb2f18f8Sesaxe #ifdef __cplusplus 30fb2f18f8Sesaxe extern "C" { 31fb2f18f8Sesaxe #endif 32fb2f18f8Sesaxe 33fb2f18f8Sesaxe #if (defined(_KERNEL) || defined(_KMEMUSER)) 34fb2f18f8Sesaxe #include <sys/cpuvar.h> 35fb2f18f8Sesaxe #include <sys/group.h> 36fb2f18f8Sesaxe #include <sys/processor.h> 37fb2f18f8Sesaxe #include <sys/bitmap.h> 38fb2f18f8Sesaxe #include <sys/atomic.h> 39fb2f18f8Sesaxe #include <sys/types.h> 40fb2f18f8Sesaxe #include <sys/kstat.h> 41fb2f18f8Sesaxe #include <sys/pg.h> 42fb2f18f8Sesaxe 43fb2f18f8Sesaxe /* 44fb2f18f8Sesaxe * Hardware that may be shared by a group of processors 45fb2f18f8Sesaxe */ 46fb2f18f8Sesaxe typedef enum pghw_type { 47fb2f18f8Sesaxe PGHW_START, 480e751525SEric Saxe PGHW_IPIPE, /* Instruction Pipeline */ 490e751525SEric Saxe PGHW_CACHE, /* Cache (generally last level) */ 500e751525SEric Saxe PGHW_FPU, /* Floating Point Unit / Pipeline */ 510e751525SEric Saxe PGHW_MPIPE, /* Pipe to Memory */ 520e751525SEric Saxe PGHW_CHIP, /* Socket */ 53fb2f18f8Sesaxe PGHW_MEMORY, 540e751525SEric Saxe PGHW_POW_ACTIVE, /* Active Power Management Domain */ 550e751525SEric Saxe PGHW_POW_IDLE, /* Idle Power Management Domain */ 56fb2f18f8Sesaxe PGHW_NUM_COMPONENTS 57fb2f18f8Sesaxe } pghw_type_t; 58fb2f18f8Sesaxe 59fb2f18f8Sesaxe /* 608031591dSSrihari Venkatesan * See comments in usr/src/uts/i86pc/os/cpuid.c 618031591dSSrihari Venkatesan * for description of processor nodes 628031591dSSrihari Venkatesan * 638031591dSSrihari Venkatesan * From sharing point of view processor nodes are 648031591dSSrihari Venkatesan * very similar to memory pipes, hence the #define below. 658031591dSSrihari Venkatesan */ 668031591dSSrihari Venkatesan #define PGHW_PROCNODE PGHW_MPIPE 678031591dSSrihari Venkatesan 688031591dSSrihari Venkatesan /* 690e751525SEric Saxe * Returns true if the hardware is a type of power management domain 700e751525SEric Saxe */ 710e751525SEric Saxe #define PGHW_IS_PM_DOMAIN(hw) \ 720e751525SEric Saxe (hw == PGHW_POW_ACTIVE || hw == PGHW_POW_IDLE) 730e751525SEric Saxe 740e751525SEric Saxe /* 75fb2f18f8Sesaxe * Anonymous instance id 76fb2f18f8Sesaxe */ 77fb2f18f8Sesaxe #define PGHW_INSTANCE_ANON ((id_t)0xdecafbad) 78fb2f18f8Sesaxe 79fb2f18f8Sesaxe /* 800e751525SEric Saxe * Max length of PGHW kstat strings 810e751525SEric Saxe */ 820e751525SEric Saxe #define PGHW_KSTAT_STR_LEN_MAX 32 830e751525SEric Saxe 840e751525SEric Saxe 850e751525SEric Saxe /* 860e751525SEric Saxe * Platform specific handle 870e751525SEric Saxe */ 880e751525SEric Saxe typedef uintptr_t pghw_handle_t; 890e751525SEric Saxe 900e751525SEric Saxe /* 91b885580bSAlexander Kolbasov * Representation of PG hardware utilization NOTE: All the sums listed below are 92b885580bSAlexander Kolbasov * the sums of running total of each item for each CPU in the PG (eg. 93b885580bSAlexander Kolbasov * sum(utilization) is sum of running total utilization of each CPU in PG) 94b885580bSAlexander Kolbasov */ 95b885580bSAlexander Kolbasov typedef struct pghw_util { 96b885580bSAlexander Kolbasov uint64_t pghw_util; /* sum(utilization) */ 97b885580bSAlexander Kolbasov uint64_t pghw_rate; /* Last observed utilization rate */ 98b885580bSAlexander Kolbasov uint64_t pghw_rate_max; /* Max observed rate (in units/sec) */ 99b885580bSAlexander Kolbasov hrtime_t pghw_time_stamp; /* Timestamp of last snapshot */ 100b885580bSAlexander Kolbasov /* 101b885580bSAlexander Kolbasov * sum(time utilization counters on) 102b885580bSAlexander Kolbasov */ 103b885580bSAlexander Kolbasov hrtime_t pghw_time_running; 104b885580bSAlexander Kolbasov /* 105b885580bSAlexander Kolbasov * sum(time utilization counters off) 106b885580bSAlexander Kolbasov */ 107b885580bSAlexander Kolbasov hrtime_t pghw_time_stopped; 108b885580bSAlexander Kolbasov } pghw_util_t; 109b885580bSAlexander Kolbasov 110b885580bSAlexander Kolbasov 111b885580bSAlexander Kolbasov /* 112fb2f18f8Sesaxe * Processor Group (physical sharing relationship) 113fb2f18f8Sesaxe */ 114fb2f18f8Sesaxe typedef struct pghw { 115fb2f18f8Sesaxe pg_t pghw_pg; /* processor group */ 116fb2f18f8Sesaxe pghw_type_t pghw_hw; /* HW sharing relationship */ 117fb2f18f8Sesaxe id_t pghw_instance; /* sharing instance identifier */ 1180e751525SEric Saxe pghw_handle_t pghw_handle; /* hw specific opaque handle */ 119fb2f18f8Sesaxe kstat_t *pghw_kstat; /* physical kstats exported */ 120b885580bSAlexander Kolbasov kstat_t *pghw_cu_kstat; /* for capacity and utilization */ 121b885580bSAlexander Kolbasov /* 122b885580bSAlexander Kolbasov * pghw_generation should be updated by superclasses whenever PG changes 123b885580bSAlexander Kolbasov * significanly (e.g. new CPUs join or leave PG). 124b885580bSAlexander Kolbasov */ 125b885580bSAlexander Kolbasov uint_t pghw_generation; /* generation number */ 126b885580bSAlexander Kolbasov 127b885580bSAlexander Kolbasov /* 128b885580bSAlexander Kolbasov * The following fields are used by PGHW cu kstats 129b885580bSAlexander Kolbasov */ 130b885580bSAlexander Kolbasov char *pghw_cpulist; /* list of CPUs */ 131b885580bSAlexander Kolbasov size_t pghw_cpulist_len; /* length of the list */ 132b885580bSAlexander Kolbasov /* 133b885580bSAlexander Kolbasov * Generation number at kstat update time 134b885580bSAlexander Kolbasov */ 135b885580bSAlexander Kolbasov uint_t pghw_kstat_gen; 136b885580bSAlexander Kolbasov pghw_util_t pghw_stats; /* Utilization data */ 137fb2f18f8Sesaxe } pghw_t; 138fb2f18f8Sesaxe 139fb2f18f8Sesaxe /* 140fb2f18f8Sesaxe * IDs associating a CPU with various physical hardware 141fb2f18f8Sesaxe */ 142fb2f18f8Sesaxe typedef struct cpu_physid { 143fb2f18f8Sesaxe id_t cpu_chipid; /* CPU's physical processor */ 144fb2f18f8Sesaxe id_t cpu_coreid; /* CPU's physical core */ 145fb2f18f8Sesaxe id_t cpu_cacheid; /* CPU's cache id */ 146fb2f18f8Sesaxe } cpu_physid_t; 147fb2f18f8Sesaxe 148fb2f18f8Sesaxe /* 149fb2f18f8Sesaxe * Physical PG initialization / CPU service hooks 150fb2f18f8Sesaxe */ 151b885580bSAlexander Kolbasov extern void pghw_init(pghw_t *, cpu_t *, pghw_type_t); 152b885580bSAlexander Kolbasov extern void pghw_fini(pghw_t *); 153b885580bSAlexander Kolbasov extern void pghw_cpu_add(pghw_t *, cpu_t *); 154b885580bSAlexander Kolbasov extern pghw_t *pghw_place_cpu(cpu_t *, pghw_type_t); 155*d3c97224SAlexander Kolbasov extern void pghw_cmt_fini(pghw_t *); 156fb2f18f8Sesaxe 157fb2f18f8Sesaxe /* 158fb2f18f8Sesaxe * Physical ID cache creation / destruction 159fb2f18f8Sesaxe */ 160b885580bSAlexander Kolbasov extern void pghw_physid_create(cpu_t *); 161b885580bSAlexander Kolbasov extern void pghw_physid_destroy(cpu_t *); 162fb2f18f8Sesaxe 163fb2f18f8Sesaxe /* 164fb2f18f8Sesaxe * CPU / PG hardware related seach operations 165fb2f18f8Sesaxe */ 166b885580bSAlexander Kolbasov extern pghw_t *pghw_find_pg(cpu_t *, pghw_type_t); 167b885580bSAlexander Kolbasov extern pghw_t *pghw_find_by_instance(id_t, pghw_type_t); 168b885580bSAlexander Kolbasov extern group_t *pghw_set_lookup(pghw_type_t); 169fb2f18f8Sesaxe 170fb2f18f8Sesaxe /* Hardware sharing relationship platform interfaces */ 171b885580bSAlexander Kolbasov extern int pg_plat_hw_shared(cpu_t *, pghw_type_t); 172b885580bSAlexander Kolbasov extern int pg_plat_cpus_share(cpu_t *, cpu_t *, pghw_type_t); 173b885580bSAlexander Kolbasov extern id_t pg_plat_hw_instance_id(cpu_t *, pghw_type_t); 174b885580bSAlexander Kolbasov extern pghw_type_t pg_plat_hw_rank(pghw_type_t, pghw_type_t); 175b885580bSAlexander Kolbasov 176b885580bSAlexander Kolbasov /* 177b885580bSAlexander Kolbasov * String representation of the hardware type 178b885580bSAlexander Kolbasov */ 179b885580bSAlexander Kolbasov extern char *pghw_type_string(pghw_type_t); 180fb2f18f8Sesaxe 181fb2f18f8Sesaxe /* 182fb2f18f8Sesaxe * What comprises a "core" may vary across processor implementations, 183fb2f18f8Sesaxe * and so the term itself is somewhat unstable. For this reason, there 184fb2f18f8Sesaxe * is no PGHW_CORE type, but we provide an interface here to allow platforms 185fb2f18f8Sesaxe * to express cpu <=> core mappings. 186fb2f18f8Sesaxe */ 187b885580bSAlexander Kolbasov extern id_t pg_plat_get_core_id(cpu_t *); 188fb2f18f8Sesaxe 189fb2f18f8Sesaxe #endif /* !_KERNEL && !_KMEMUSER */ 190fb2f18f8Sesaxe 191fb2f18f8Sesaxe #ifdef __cplusplus 192fb2f18f8Sesaxe } 193fb2f18f8Sesaxe #endif 194fb2f18f8Sesaxe 195fb2f18f8Sesaxe #endif /* _PGHW_H */ 196