machdep.c revision 53391baf4e45c693cf123555e9617b5e1e0b641a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/promimpl.h>
#include <sys/privregs.h>
#include "cprboot.h"
#define TIMEOUT_MSECS 1000
/*
* globals
*/
int cpr_test_mode;
/*
* file scope
*/
static int has_scbc;
/*
* check machdep desc and cpr_machdep info
*
* sets globals:
* mdinfo
* mdlen
*/
int
cb_check_machdep(void)
{
str = "cb_check_machdep";
/*
* get machdep desc and set length of prom words
*/
prom_printf("%s: bad machdep magic 0x%x, expect 0x%x\n",
return (ERR);
}
/*
* get machep info, check for valid stack bias and wstate
*/
fmt = "found bad statefile data: %s (0x%x), expect 0x%x or 0x%x\n";
return (ERR);
}
return (ERR);
}
return (0);
}
/*
* interpret saved prom words
*/
int
cb_interpret(void)
{
char minibuf[60];
char *words;
/*
* The variable length machdep section for sun4u consists of
* a sequence of null-terminated strings stored contiguously.
*
* The first string defines Forth words which help the prom
* handle kernel translations.
*
* The second string defines Forth words required by kadb to
* interface with the prom when a trap is taken.
*/
while (bytes) {
if (verbose) {
s = sizeof (minibuf) - 4;
if (wlen > s)
}
prom_interpret(words, 0, 0, 0, 0, 0);
}
/* advance past prom words */
return (0);
}
/*
*/
static void
{
char tname;
tname = 'd';
tname = 'i';
}
continue;
prom_printf(" cpu_id %d: write %ctlb "
"(index %x, virt 0x%lx, size 0x%x)\n",
}
}
}
/*
* install locked tlb entries for the kernel and cpr module;
* also sets up the tmp stack
*/
int
cb_ksetup(void)
{
return (0);
}
static void
cb_park_err(int cpu_id)
{
}
/*
* local copy of an older interface for OBP revs < 4.6
*/
static int
cb_prom_stop_self(void)
{
return (0);
}
/*
* install locked tlb entries and spin or park in a prom idle-loop
*/
void
slave_init(int cpu_id)
{
membar_stld();
if (has_scbc) {
/* just spin, master will park this cpu */
/* CONSTCOND */
while (1);
} else {
(void) cb_prom_stop_self();
}
}
/*
* when any cpu is started, they naturally rely on the prom for all
* to jump back into the cpr module and to restart slave cpus, cprboot
* needs to reinstall translations for the nucleus and some cpr pages.
*
* the easy method is creating one set of global translations available
* to all cpus with prom_map(); unfortunately, a 4MB "map" request will
* allocate and overwrite a few pages, and these are often kernel pages
* that were just restored.
*
* to solve the "map" problem, all cpus install their own set of locked
* tlb entries to translate the nucleus and parts of the cpr module;
* after all cpus have switched to kernel traps, any of these locked
* tlb entries for pages outside the nucleus will be cleared.
*/
int
cb_mpsetup(void)
{
intf = "SUNW,stop-cpu-by-cpuid";
str = "cb_mp_setup";
/*
* launch any slave cpus from the .sci array into cprboot text
* and wait about a second for them to checkin with slave_set
*/
ncpu = 0;
continue;
break;
}
if (timeout == 0) {
prom_printf("\n%s: cpu did not start, "
"cpu_id %d, node 0x%x\n",
return (ERR);
}
ncpu++;
}
return (0);
}