/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <sys/machsystm.h>
#include <sys/platform_module.h>
#include <sys/cpu_module.h>
#include <sys/cpu_sgnblk_defs.h>
typedef const char *fn_t;
/*
* flags to determine if the PROM routines
*/
static int cpu_are_paused;
extern void debug_flush_windows();
/*
* Initialize the idlestop mutex
*/
void
idlestop_init(void)
{
}
static void
cpu_idle_self(void)
{
uint_t s;
s = spl8();
membar_stld();
membar_stld();
splx(s);
}
void
idle_other_cpus(void)
{
int failed = 0;
if (ncpus == 1)
return;
if (CPUSET_ISNULL(cpu_idle_set))
return;
for (i = 0; i < NCPU; i++) {
if (!CPU_IN_SET(cpu_idle_set, i))
continue;
ntries = 0x10000;
DELAY(50);
ntries--;
}
/*
* A cpu failing to idle is an error condition, since
* we can't be sure anymore of its state.
*/
failed++;
}
}
if (failed) {
}
}
void
resume_other_cpus(void)
{
int i, ntries;
if (ncpus == 1)
return;
for (i = 0; i < NCPU; i++) {
if (!CPU_IN_SET(cpu_idle_set, i))
continue;
kern_idle[i] = 0;
membar_stld();
}
for (i = 0; i < NCPU; i++) {
if (!CPU_IN_SET(cpu_idle_set, i))
continue;
ntries = 0x10000;
DELAY(50);
ntries--;
}
/*
* A cpu failing to resume is an error condition, since
* intrs may have been directed there.
*/
continue;
}
CPUSET_DEL(cpu_idle_set, i);
}
/*
* Non-zero if a cpu failed to resume
*/
if (failed)
}
/*
* Stop all other cpu's before halting or rebooting. We pause the cpu's
* instead of sending a cross call.
*/
void
stop_other_cpus(void)
{
if (cpu_are_paused) {
return;
}
if (ncpus > 1)
cpu_are_paused = 1;
}
void
{
static fn_t f = "mp_cpu_quiesce";
/*
* Declare CPU as no longer being READY to process interrupts and
* wait for them to stop. A CPU that is not READY can no longer
* participate in x-calls or x-traps.
*/
membar_sync();
for (i = 0; i < sanity_limit; i++) {
if (cp->cpu_intr_actv == 0 &&
found_intr = 0;
break;
}
DELAY(1);
}
if (found_intr) {
if (cp->cpu_intr_actv) {
f, cpuid);
}
}
}
/*
* Start CPU on user request.
*/
/* ARGSUSED */
int
{
/*
* Platforms that use CPU signatures require the signature
* block update to indicate that this CPU is in the OS now.
*/
return (0); /* nothing special to do on this arch */
}
/*
* Stop CPU on user request.
*/
/* ARGSUSED */
int
{
/*
* Platforms that use CPU signatures require the signature
* block update to indicate that this CPU is offlined now.
*/
return (0); /* nothing special to do on this arch */
}
/*
* Power on CPU.
*/
int
{
if (&plat_cpu_poweron)
return (ENOTSUP);
}
/*
* Power off CPU.
*/
int
{
if (&plat_cpu_poweroff)
return (ENOTSUP);
}
void
{
}
void
{
}