chip.h revision 8949bcd619d78e849deef983cb8310bc3aa3e242
369N/A/*
369N/A * CDDL HEADER START
369N/A *
369N/A * The contents of this file are subject to the terms of the
369N/A * Common Development and Distribution License, Version 1.0 only
369N/A * (the "License"). You may not use this file except in compliance
369N/A * with the License.
369N/A *
369N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
369N/A * or http://www.opensolaris.org/os/licensing.
369N/A * See the License for the specific language governing permissions
369N/A * and limitations under the License.
369N/A *
369N/A * When distributing Covered Code, include this CDDL HEADER in each
369N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
369N/A * If applicable, add the following below this CDDL HEADER, with the
369N/A * fields enclosed by brackets "[]" replaced with your own identifying
369N/A * information: Portions Copyright [yyyy] [name of copyright owner]
369N/A *
369N/A * CDDL HEADER END
1069N/A */
369N/A/*
369N/A * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
369N/A * Use is subject to license terms.
369N/A */
1001N/A
369N/A#ifndef _CHIP_H
369N/A#define _CHIP_H
389N/A
369N/A#pragma ident "%Z%%M% %I% %E% SMI"
1069N/A
369N/A/*
1069N/A * generic kernel CMT processor support
1001N/A */
986N/A
1069N/A#ifdef __cplusplus
1069N/Aextern "C" {
369N/A#endif
1071N/A
1069N/A#if (defined(_KERNEL) || defined(_KMEMUSER))
1069N/A#include <sys/cpuvar.h>
986N/A#include <sys/processor.h>
1001N/A#include <sys/bitmap.h>
369N/A#include <sys/atomic.h>
369N/A#include <sys/types.h>
369N/A
1069N/A/*
1069N/A * Chip types
1069N/A */
1069N/Atypedef enum chip_type {
1069N/A CHIP_DEFAULT, /* Default, non CMT processor */
1069N/A CHIP_SMT, /* SMT, single core */
1069N/A CHIP_CMP_SPLIT_CACHE, /* CMP with split caches */
1069N/A CHIP_CMP_SHARED_CACHE, /* CMP with shared caches */
1069N/A CHIP_CMT, /* CMT w/ multiple cores and threads */
1069N/A CHIP_NUM_TYPES
1069N/A} chip_type_t;
1069N/A
1069N/A
1069N/A/*
1069N/A * Balancing is possible if multiple chips exist in the lgroup
1069N/A * but only necessary if the chip has multiple online logical CPUs
1069N/A */
1069N/A#define CHIP_SHOULD_BALANCE(chp) \
1069N/A (((chp)->chip_ncpu > 1) && ((chp)->chip_next_lgrp != (chp)))
1069N/A
1069N/A/*
1069N/A * Platform's definition of a chip's properties
1069N/A */
1069N/Atypedef struct chip_def {
1069N/A chip_type_t chipd_type;
1069N/A int chipd_rechoose_adj;
1069N/A} chip_def_t;
1069N/A
1069N/A/*
1069N/A * Per chip kstats
1069N/A */
1069N/Atypedef enum chip_stat_types {
1069N/A CHIP_ID, /* chip "id" */
1069N/A CHIP_NCPUS, /* number of active cpus */
1069N/A CHIP_NRUNNING, /* number of running threads on chip */
1069N/A CHIP_RECHOOSE, /* chip's rechoose_interval */
1069N/A CHIP_NUM_STATS /* always last */
1069N/A} chip_stat_t;
1069N/A
1069N/A#define CHIP_KSTAT_NAMES \
1069N/Astatic char *chip_kstat_names[] = { \
1069N/A \
1069N/A "chip_id", \
1069N/A "logical_cpus", \
1069N/A "chip_nrunning", \
1069N/A "chip_rechoose_interval", \
1069N/A}
1069N/A
1069N/A/*
1069N/A * Physical processor (chip) structure.
1069N/A */
1069N/Atypedef struct chip {
1069N/A chipid_t chip_id; /* chip's "id" */
1069N/A chipid_t chip_seqid; /* sequential id */
1069N/A struct chip *chip_prev; /* previous chip on list */
1069N/A struct chip *chip_next; /* next chip on list */
1069N/A struct chip *chip_prev_lgrp; /* prev chip in lgroup */
1069N/A struct chip *chip_next_lgrp; /* next chip in lgroup */
1069N/A chip_type_t chip_type; /* type of chip */
1069N/A uint16_t chip_ncpu; /* number of active cpus */
1069N/A uint16_t chip_ref; /* chip's reference count */
1069N/A struct cpu *chip_cpus; /* per chip cpu list */
1069N/A struct lgrp *chip_lgrp; /* chip lives in this lgroup */
1069N/A int chip_rechoose_adj; /* chip specific adjustment */
1069N/A
1069N/A /*
1069N/A * chip kstats
1069N/A */
1069N/A kstat_t *chip_kstat;
1069N/A kmutex_t chip_kstat_mutex;
1069N/A struct kstat_named chip_kstat_data[CHIP_NUM_STATS];
1069N/A
1069N/A struct chip *chip_balance; /* chip to balance against */
1069N/A uint32_t chip_nrunning; /* # of running threads */
1069N/A} chip_t;
1069N/A
1069N/A/*
1069N/A * Change the number of running threads on the chip
1069N/A */
1069N/A#define CHIP_NRUNNING(chp, n) { \
1069N/A atomic_add_32(&((chp)->chip_nrunning), (n)); \
1069N/A}
1069N/A
1069N/A/*
1071N/A * True if this CPU is active on the chip
1071N/A */
1069N/A#define CHIP_CPU_ACTIVE(cp) ((cp)->cpu_next_chip != NULL)
1069N/A
1069N/A/*
1069N/A * Sets of chips
1069N/A * The "id" used here should be a chip's sequential id.
1069N/A * (chip_seqid)
1069N/A */
1069N/A#if defined(_MACHDEP)
1069N/A
1069N/A#define CHIP_MAX_CHIPS NCPU
1069N/A#define CHIP_SET_WORDS BT_BITOUL(CHIP_MAX_CHIPS)
1069N/A
1069N/Atypedef struct chip_set {
1069N/A ulong_t csb[CHIP_SET_WORDS];
1069N/A} chip_set_t;
1069N/A
1069N/Aextern int chip_set_isnull(chip_set_t *);
1071N/A
1071N/A#define CHIP_SET_ISNULL(set) chip_set_isnull(&(set))
1071N/A#define CHIP_SET_TEST(set, id) BT_TEST((set).csb, id)
1071N/A#define CHIP_SET_REMOVE(set, id) BT_CLEAR((set).csb, id)
1071N/A#define CHIP_SET_ADD(set, id) BT_SET((set).csb, id)
1071N/A
1071N/A#define CHIP_SET_ZERO(set) { \
1071N/A int _i; \
1071N/A for (_i = 0; _i < CHIP_SET_WORDS; _i++) \
1071N/A (set).csb[_i] = 0; \
1071N/A}
1071N/A
1071N/A#define CHIP_IN_CPUPART(chp, cp) \
1071N/A (CHIP_SET_TEST((cp)->cp_chipset, (chp)->chip_seqid))
1071N/A
1071N/A#endif /* _MACHDEP */
1071N/A
1071N/A/*
1071N/A * Common kernel chip operations
1071N/A */
1071N/Avoid chip_cpu_init(cpu_t *);
1071N/Avoid chip_cpu_fini(cpu_t *);
1071N/Avoid chip_cpu_assign(cpu_t *);
1071N/Avoid chip_cpu_unassign(cpu_t *);
1071N/Avoid chip_cpu_startup(cpu_t *);
1071N/Avoid chip_bootstrap_cpu(cpu_t *);
1071N/A
1071N/Avoid chip_cpu_move_part(cpu_t *, struct cpupart *,
1071N/A struct cpupart *);
1071N/A
1071N/Avoid chip_kstat_create(chip_t *);
1071N/A
1071N/A/*
1071N/A * Platform chip operations
1071N/A */
1071N/Achipid_t chip_plat_get_chipid(cpu_t *);
1071N/Aid_t chip_plat_get_coreid(cpu_t *);
1071N/Aint chip_plat_get_clogid(cpu_t *);
1071N/Avoid chip_plat_define_chip(cpu_t *, chip_def_t *);
1071N/A
1071N/A#endif /* !_KERNEL && !_KMEMUSER */
1071N/A
1071N/A#ifdef __cplusplus
1071N/A}
1071N/A#endif
1071N/A
1071N/A#endif /* _CHIP_H */
1071N/A