chip.c revision 25cf1a301a396c38e8adf52c15f537b80d2483f7
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Common Development and Distribution License (the "License").
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/types.h>
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley#include <sys/param.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/thread.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/cpuvar.h>
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley#include <sys/cpupart.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/kmem.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/cmn_err.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/kstat.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/processor.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/disp.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <sys/chip.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CMT aware scheduler/dispatcher support
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * With the introduction of Chip Multi-Threaded (CMT) processor architectures,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * it is no longer necessarily true that a given physical processor
fa9e4066f08beec538e775443c5be79dd423fcabahrens * module (chip) will present itself as a single schedulable entity (cpu_t).
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Rather, each chip may present itself as one or more "logical" CPUs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The logical CPUs presented may share physical components on the chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens * such as caches, data pipes, FPUs, etc. It is advantageous to have the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * kernel know which logical CPUs are presented by a given chip,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and what facilities on the chip are shared, since the kernel can then use
fa9e4066f08beec538e775443c5be79dd423fcabahrens * this information to employ scheduling policies that help improve the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * availability of per chip resources, and increase utilization of a thread's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * cache investment.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The "chip_t" structure represents a physical processor.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * It is used to keep track of which logical CPUs are presented by a given
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip, and to provide a parameterized representation of a chip's
fa9e4066f08beec538e775443c5be79dd423fcabahrens * properties. A count of the number of running threads is also
fa9e4066f08beec538e775443c5be79dd423fcabahrens * maintained, and is used by the dispatcher to balance load across the
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * system's chips to improve performance through increased chip resource
fa9e4066f08beec538e775443c5be79dd423fcabahrens * availability.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Locking:
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Safely traversing the per lgroup lists requires the same protections
fa9e4066f08beec538e775443c5be79dd423fcabahrens * as traversing the cpu lists. One must either:
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - hold cpu_lock
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - have disabled kernel preemption
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - be at high SPL
fa9e4066f08beec538e775443c5be79dd423fcabahrens * - have cpu's paused
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Safely traversing the global "chip_list" requires holding cpu_lock.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A chip's nrunning count should only be modified using the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CHIP_NRUNNING() macro, through which updates of the count are done
fa9e4066f08beec538e775443c5be79dd423fcabahrens * atomically.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_t cpu0_chip; /* chip structure for first CPU */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip_bootstrap is used on platforms where it is possible to enter the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * dispatcher before a new CPU's chip initialization has happened.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_t chip_bootstrap;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#define CPU_HAS_NO_CHIP(cp) \
fa9e4066f08beec538e775443c5be79dd423fcabahrens ((cp)->cpu_chip == NULL || (cp)->cpu_chip == &chip_bootstrap)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_t *chip_list; /* protected by CPU lock */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_set_t chip_set; /* bitmap of chips in existence */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* indexed by chip_seqid */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chipid_t chip_seqid_next = 0; /* next sequential chip id */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int nchips = 0; /* num chips in existence */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_t *chip_find(chipid_t);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int chip_kstat_extract(kstat_t *, int);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Declare static kstat names (defined in chip.h)
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensCHIP_KSTAT_NAMES;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find the chip_t with the given chip_id.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic chip_t *
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_find(chipid_t chipid)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp, *chip_start;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list == NULL || chip_list->chip_next == chip_list ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if ((chp = chip_start = chip_list) != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens do {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp->chip_id == chipid) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (chp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens } while ((chp = chp->chip_next) != chip_start);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_t *
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_lookup(chipid_t chipid)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_enter(&cpu_lock);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = chip_find(chipid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_exit(&cpu_lock);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (chp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#ifndef sun4v
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Setup the kstats for this chip, if needed
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_kstat_create(chip_t *chp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_stat_t stat;
fa9e4066f08beec538e775443c5be79dd423fcabahrens kstat_t *chip_kstat;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp->chip_kstat != NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return; /* already initialized */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat = kstat_create("chip", chp->chip_id, NULL, "misc",
fa9e4066f08beec538e775443c5be79dd423fcabahrens KSTAT_TYPE_NAMED, CHIP_NUM_STATS,
fa9e4066f08beec538e775443c5be79dd423fcabahrens KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chip_kstat != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat->ks_lock = &chp->chip_kstat_mutex;
fa9e4066f08beec538e775443c5be79dd423fcabahrens mutex_init(chip_kstat->ks_lock, NULL, MUTEX_DEFAULT, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat->ks_private = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat->ks_data = chp->chip_kstat_data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (stat = 0; stat < CHIP_NUM_STATS; stat++)
fa9e4066f08beec538e775443c5be79dd423fcabahrens kstat_named_init(&chp->chip_kstat_data[stat],
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat_names[stat], KSTAT_DATA_INT64);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat->ks_update = chip_kstat_extract;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_kstat = chip_kstat;
fa9e4066f08beec538e775443c5be79dd423fcabahrens kstat_install(chip_kstat);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Note: On sun4v systems, chip kstats don't currently
fa9e4066f08beec538e775443c5be79dd423fcabahrens * exist, since "chip" structures and policies are being
fa9e4066f08beec538e775443c5be79dd423fcabahrens * leveraged to implement core level balancing, and exporting
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip kstats in light of this would be both misleading
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and confusing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_kstat_create(chip_t *chp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* !sun4v */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_kstat_extract(kstat_t *ksp, int rw)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct kstat_named *ksd;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = (chip_t *)ksp->ks_private;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksd = (struct kstat_named *)ksp->ks_data;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(ksd == chp->chip_kstat_data);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The chip kstats are read only
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (rw == KSTAT_WRITE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (EACCES);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksd[CHIP_ID].value.i64 = chp->chip_id;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksd[CHIP_NCPUS].value.i64 = chp->chip_ncpu;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksd[CHIP_NRUNNING].value.i64 = chp->chip_nrunning;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ksd[CHIP_RECHOOSE].value.i64 =
fa9e4066f08beec538e775443c5be79dd423fcabahrens rechoose_interval + chp->chip_rechoose_adj;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If necessary, instantiate a chip_t for this CPU.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Called when a CPU is being added to the system either in startup,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or because of DR. The cpu will be assigned to the chip's active
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CPU list later in chip_cpu_assign()
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_init(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chipid_t cid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int rechoose;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_def_t chp_def;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT((chip_list == NULL) || (MUTEX_HELD(&cpu_lock)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Call into the platform to fetch this cpu's chipid
fa9e4066f08beec538e775443c5be79dd423fcabahrens * On sun4v platforms, the chip infrastructure is currently being
fa9e4066f08beec538e775443c5be79dd423fcabahrens * leveraged to implement core level load balancing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#ifdef DO_CORELEVEL_LOADBAL
fa9e4066f08beec538e775443c5be79dd423fcabahrens cid = chip_plat_get_coreid(cp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#else
fa9e4066f08beec538e775443c5be79dd423fcabahrens cid = chip_plat_get_chipid(cp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif /* DO_CORELEVEL_LOADBAL */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = chip_find(cid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Create a new chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chip_list == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = &cpu0_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = kmem_zalloc(sizeof (*chp), KM_SLEEP);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_id = cid;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_nrunning = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we're booting, take this moment to perform
fa9e4066f08beec538e775443c5be79dd423fcabahrens * some additional initialization
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chip_list == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_SET_ZERO(chip_set);
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_SET_ZERO(cp->cpu_part->cp_chipset);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_nrunning++; /* for t0 */
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Find the next free sequential chip id.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A chip's sequential id exists in the range
fa9e4066f08beec538e775443c5be79dd423fcabahrens * 0 .. CHIP_MAX_CHIPS, and is suitable for use with
fa9e4066f08beec538e775443c5be79dd423fcabahrens * chip sets.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens while (CHIP_SET_TEST(chip_set, chip_seqid_next))
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_seqid_next++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_seqid = chip_seqid_next++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_SET_ADD(chip_set, chp->chip_seqid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_seqid_next <= CHIP_MAX_CHIPS);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Query the platform specific parameters
fa9e4066f08beec538e775443c5be79dd423fcabahrens * for this chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_plat_define_chip(cp, &chp_def);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_rechoose_adj = chp_def.chipd_rechoose_adj;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_type = chp_def.chipd_type;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT((chp->chip_type < CHIP_NUM_TYPES) &&
fa9e4066f08beec538e775443c5be79dd423fcabahrens (chp->chip_type >= CHIP_DEFAULT));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Insert this chip in chip_list
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chip_list == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_list = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_next = chp->chip_prev = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chptr = chip_list;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_next = chptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_prev = chptr->chip_prev;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chptr->chip_prev->chip_next = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chptr->chip_prev = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens nchips++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(nchips <= CHIP_MAX_CHIPS);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The boot cpu will create the first chip's kstats
fa9e4066f08beec538e775443c5be79dd423fcabahrens * later in cpu_kstat_init()
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp != &cpu0_chip)
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_kstat_create(chp);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize the effective rechoose interval cached
fa9e4066f08beec538e775443c5be79dd423fcabahrens * in this cpu structure.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens rechoose = rechoose_interval + chp->chip_rechoose_adj;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_rechoose = (rechoose < 0) ? 0 : rechoose;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_chip = chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_ref++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is being deleted. It has already been removed from
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the chip's active cpu list back in chip_cpu_unassign(). Here
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we remove the cpu's reference to the chip, and cleanup/destroy
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the chip if needed.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_fini(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *prev, *next;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This can happen if the CPU failed to power on
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley if (CPU_HAS_NO_CHIP(cp))
3349c8dc868dbab8bd2e9355b835f83837de8900talley return;
3349c8dc868dbab8bd2e9355b835f83837de8900talley
3349c8dc868dbab8bd2e9355b835f83837de8900talley chp = cp->cpu_chip;
3349c8dc868dbab8bd2e9355b835f83837de8900talley cp->cpu_chip = NULL;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley if (--chp->chip_ref == 0) {
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley /*
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * make sure the chip is really empty
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley */
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley ASSERT(chp->chip_ncpu == 0);
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley ASSERT(chp->chip_cpus == NULL);
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley ASSERT(chp->chip_nrunning == 0);
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley ASSERT(chp->chip_lgrp == NULL);
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley ASSERT((chp->chip_next_lgrp == NULL) &&
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley (chp->chip_prev_lgrp == NULL));
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley if (chip_seqid_next > chp->chip_seqid)
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley chip_seqid_next = chp->chip_seqid;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley CHIP_SET_REMOVE(chip_set, chp->chip_seqid);
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley chp->chip_id = -1;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley chp->chip_seqid = -1;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley /*
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley * remove the chip from the system's chip list
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley */
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley if (chip_list == chp)
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley chip_list = chp->chip_next;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley prev = chp->chip_prev;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley next = chp->chip_next;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
3349c8dc868dbab8bd2e9355b835f83837de8900talley prev->chip_next = next;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley next->chip_prev = prev;
3349c8dc868dbab8bd2e9355b835f83837de8900talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley chp->chip_next = chp->chip_prev = NULL;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley nchips--;
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley /*
3349c8dc868dbab8bd2e9355b835f83837de8900talley * clean up any chip kstats
fbfd10ff571cfd0139aa5127460f1b8a53dac971talley */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp->chip_kstat) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens kstat_delete(chp->chip_kstat);
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_kstat = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If the chip_t structure was dynamically
fa9e4066f08beec538e775443c5be79dd423fcabahrens * allocated, free it.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp != &cpu0_chip)
fa9e4066f08beec538e775443c5be79dd423fcabahrens kmem_free(chp, sizeof (*chp));
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is becoming active (online).
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Perform all the necessary bookkeeping in it's chip_t
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_assign(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cpu_t *cptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list == NULL || chip_list->chip_next == chip_list ||
fa9e4066f08beec538e775443c5be79dd423fcabahrens MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = cp->cpu_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add this cpu to the chip's cpu list
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp->chip_ncpu == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_cpus = cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_next_chip = cp->cpu_prev_chip = cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cptr = chp->chip_cpus;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_next_chip = cptr;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_prev_chip = cptr->cpu_prev_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_prev_chip->cpu_next_chip = cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens cptr->cpu_prev_chip = cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_ncpu++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Notate this chip's seqid in the cpu partition's chipset
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_cpu_move_part(cp, NULL, cp->cpu_part);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This cpu is being offlined, so do the reverse
fa9e4066f08beec538e775443c5be79dd423fcabahrens * of cpu_chip_assign()
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_unassign(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct cpu *prev;
fa9e4066f08beec538e775443c5be79dd423fcabahrens struct cpu *next;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = cp->cpu_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_cpu_move_part(cp, cp->cpu_part, NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * remove this cpu from the chip's cpu list
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens prev = cp->cpu_prev_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens next = cp->cpu_next_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens prev->cpu_next_chip = next;
fa9e4066f08beec538e775443c5be79dd423fcabahrens next->cpu_prev_chip = prev;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_next_chip = cp->cpu_prev_chip = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_ncpu--;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (chp->chip_ncpu == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_cpus = NULL;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (chp->chip_cpus == cp) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp->chip_cpus = next;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * A cpu on the chip is moving into and/or out of a cpu partition.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Maintain the cpuparts' chip membership set.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * oldpp is NULL when a cpu is being offlined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * newpp is NULL when a cpu is being onlined.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_move_part(cpu_t *cp, cpupart_t *oldpp, cpupart_t *newpp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens cpu_t *cpp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens chip_t *chp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens ASSERT(chip_list->chip_next == chip_list || MUTEX_HELD(&cpu_lock));
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens chp = cp->cpu_chip;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (newpp != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Add the chip's seqid to the cpupart's chip set
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_SET_ADD(newpp->cp_chipset, chp->chip_seqid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (oldpp != NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens cpp = cp;
fa9e4066f08beec538e775443c5be79dd423fcabahrens while ((cpp = cpp->cpu_next_chip) != cp) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cpp->cpu_part->cp_id == oldpp->cp_id) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Another cpu on the chip is in the old
fa9e4066f08beec538e775443c5be79dd423fcabahrens * cpu partition, so we're done
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens return;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * No other cpu on the chip is in the old partition
fa9e4066f08beec538e775443c5be79dd423fcabahrens * so remove the chip's seqid from it's set
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_SET_REMOVE(oldpp->cp_chipset, chp->chip_seqid);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Called to indicate a slave CPU has started up.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_cpu_startup(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Indicate that the chip has a new running thread
fa9e4066f08beec538e775443c5be79dd423fcabahrens * (slave startup)
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens CHIP_NRUNNING(cp->cpu_chip, 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Provide the specified CPU a bootstrap chip
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensvoid
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_bootstrap_cpu(cpu_t *cp)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens cp->cpu_chip = &chip_bootstrap;
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Given a chip set, return 1 if it is empty.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrensint
fa9e4066f08beec538e775443c5be79dd423fcabahrenschip_set_isnull(chip_set_t *set)
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < CHIP_SET_WORDS; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (set->csb[i] != 0)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens