us3_jalapeno.c revision db874c57ae335a07060499f1492b0d0e2593e26c
/*
* 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/sysmacros.h>
#include <sys/archsystm.h>
#include <sys/machparam.h>
#include <sys/machsystm.h>
#include <sys/machthread.h>
#include <sys/elf_SPARC.h>
#include <vm/hat_sfmmu.h>
#include <vm/seg_kmem.h>
#include <sys/cheetahregs.h>
#include <sys/us3_module.h>
#include <sys/dditypes.h>
#include <sys/prom_debug.h>
#include <sys/prom_plat.h>
#include <sys/cpu_module.h>
#include <sys/sysmacros.h>
#include <sys/platform_module.h>
#include <sys/machtrap.h>
#include <sys/bootconf.h>
#include <sys/errclassify.h>
#ifdef CHEETAHPLUS_ERRATUM_25
#endif /* CHEETAHPLUS_ERRATUM_25 */
/* cpu estar private data */
typedef struct {
#if defined(JALAPENO) && defined(JALAPENO_ERRATA_85)
/*
* JP Errata 85 workaround.
*
* jp_errata_85_allow_slow_scrub is usually set to !jp_errata_85_enable,
* to run in 1/2 or 1/32 mode. If a cpu is vulnerable to errata 85,
* this value should be zero.
*
* jp_errata_85_active is an internal variable and must not be
*/
extern int jp_errata_85_enable; /* for /etc/system use */
extern int jp_errata_85_allow_slow_scrub; /* for /etc/system use */
#endif /* JALAPENO && JALAPENO_ERRATA_85 */
/*
* Setup trap handlers.
*/
void
cpu_init_trap(void)
{
}
static int
{
int value;
case sizeof (int):
break;
default:
break;
}
return (value);
}
/*
* Set the magic constants of the implementation.
*/
/*ARGSUSED*/
void
{
int i, a;
static struct {
char *name;
int *var;
int defval;
} prop[] = {
};
i = 0; a = vac_size;
while (a >>= 1)
++i;
vac_shift = i;
vac = 1;
}
void
{
#ifdef CHEETAHPLUS_ERRATUM_25
int recovered = 0;
int cpuid;
#endif
/*
* will be used for dispatching interrupt. For now, assume
* there are no more than IDSR_BN_SETS CPUs, hence no aliasing
*/
for (i = 0; i < NCPU; i++)
if (CPU_IN_SET(set, i)) {
cpuids[CPUID_TO_BN_PAIR(i)] = i;
shipped++;
CPUSET_DEL(set, i);
if (CPUSET_ISNULL(set))
break;
}
for (;;) {
if (idsr == 0)
break;
/*
* If there is a big jump between the current tick
* count and lasttick, we have probably hit a break
* point. Adjust endtick accordingly to avoid panic.
*/
if (panic_quiesce)
return;
#ifdef CHEETAHPLUS_ERRATUM_25
cpuid = -1;
for (i = 0; i < IDSR_BN_SETS; i++) {
if (idsr & (IDSR_NACK_BIT(i) |
IDSR_BUSY_BIT(i))) {
break;
}
}
recovered == 0) {
if (mondo_recover(cpuid, i)) {
/*
* We claimed the whole memory or
* full scan is disabled.
*/
recovered++;
}
/*
* Recheck idsr
*/
continue;
} else
#endif /* CHEETAHPLUS_ERRATUM_25 */
{
"[%d NACK %d BUSY]\nIDSR 0x%"
for (i = 0; i < IDSR_BN_SETS; i++) {
if (idsr & (IDSR_NACK_BIT(i) |
IDSR_BUSY_BIT(i))) {
cpuids[i]);
}
}
}
}
if (curbusy) {
busy++;
continue;
}
#ifdef SEND_MONDO_STATS
{
if (n < 8192)
x_nack_stimes[n >> 7]++;
}
#endif
;
do {
i = IDSR_NACK_IDX(lo);
} while (curnack);
nack++;
busy = 0;
}
#ifdef SEND_MONDO_STATS
{
if (n < 8192)
x_set_stimes[n >> 7]++;
else
}
x_set_cpus[shipped]++;
#endif
}
/*
* Handles error logging for implementation specific error types
*/
int
{
case CPU_IC_PARITY:
return (CH_ASYNC_LOG_DONE);
case CPU_DC_PARITY:
return (CH_ASYNC_LOG_DONE);
case CPU_RCE:
return (CH_ASYNC_LOG_RECIRC);
}
/*FALLTHRU*/
/*
* cases where we just want to report the error and continue.
*/
case CPU_BPAR:
case CPU_UMS:
case CPU_FRC:
case CPU_FRU:
return (CH_ASYNC_LOG_DONE);
/*
* Cases where we want to fall through to handle panicking.
*/
case CPU_RUE:
return (CH_ASYNC_LOG_CONTINUE);
default:
return (CH_ASYNC_LOG_UNKNOWN);
}
}
/*
* Figure out if Ecache is direct-mapped (Cheetah or Cheetah+ with Ecache
* control ECCR_ASSOC bit off or 2-way (Cheetah+ with ECCR_ASSOC on).
* We need to do this on the fly because we may have mixed Cheetah+'s with
* both direct and 2-way Ecaches.
*/
int
cpu_ecache_nway(void)
{
return (JP_ECACHE_NWAY);
}
/*
* Note that these are entered into the table in the order:
*
* Afar overwrite policy is:
* Jalapeno:
* UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC >
* TO,BERR > UMS,OM
* Serrano:
* UCU,UCC > RUE,UE,EDU,WDU,CPU,WBP,BP > RCE,CE,EDC,WDC,CPC,ETI,ETC >
* TO,BERR > UMS,OM
*/
/* Fatal Errors */
"JETO Fatal",
"SCE Fatal",
"JEIC Fatal",
"JEIT Fatal",
"JEIS Fatal",
#if defined(JALAPENO)
"ETP Fatal",
"ETS Fatal",
"ETU Fatal",
#endif /* SERRANO */
"IERR Fatal",
"ISAP Fatal",
"Orphaned UCU",
"Orphaned UCC",
/* UCU, UCC */
"UCU",
"UCC",
/* RUE, UE, EDU:ST, EDU:BLD, WDU, CPU, BP, WBP */
"Uncorrectable memory (UE)",
"EDU:ST",
"EDU:BLD",
"WDU",
"CPU",
"JBUS parity error on writeback or block store (WBP)",
"JBUS parity error on returned read data (BP)",
/* RCE, CE, EDC, WDC, CPC */
"Corrected memory (CE)",
"EDC",
"WDC",
"CPC",
#if defined(SERRANO)
/* ETI, ETC */
"ETI",
"ETC",
#endif /* SERRANO */
/* TO, BERR */
"Timeout (TO)",
"Bus Error (BERR)",
/* UMS, OM */
"Unsupported store (UMS)",
"Out of range memory (OM)",
/* FRC, FRU */
"Corrected memory (FRC)",
"Uncorrectable memory (FRU)",
/* IVPE */
"IVPE",
0, NULL, 0, 0,
NULL,
};
/*
* J_REQ overwrite policy (see UltraSPARC-IIIi PRM)
*
* Class 4: RUE, BP, WBP
* Class 3: RCE
* Class 2: TO, BERR
* Class 1: UMS
*/
uint64_t jreq_overwrite[] = {
0
};
/*
* AGENT ID overwrite policy (see UltraSPARC-IIIi PRM)
*
* Class 2: CPU, FRU
* Class 1: CPC, FRC
*/
uint64_t jbus_aid_overwrite[] = {
0
};
int
{
}
/*
* See UltraSPARC-IIIi+ PRM
* Class 5: ETS, ETU, EFES
* Class 4: UCC, UCU
* Class 3: UE, RUE, BP, WBP, EDU, WDU, CPU
* Class 2: CE, RCE, EDC, WDC, CPC, ETI, ETC
* Class 1: TO, BERR
* Class 0: UMS, OM
*
* See UltraSPARC-IIIi PRM
* Class 5: ETP
* Class 4: UCC, UCU
* Class 3: UE, RUE, BP, WBP, EDU, WDU
* Class 2: CE, RCE, EDC, WDC
* Class 1: TO, BERR
* Class 0: UMS, OM
*/
uint64_t afar_overwrite[] = {
#if defined(JALAPENO)
#endif /* SERRANO */
#if defined(SERRANO)
C_AFSR_ETI | C_AFSR_ETC |
#endif /* SERRANO */
0
};
#if defined(SERRANO)
/*
* Serrano has a second AFAR that captures the physical address on
* captures the address for UE and CE errors.
*
* See UltraSPARC-IIIi+ PRM
* Class 3: UE
* Class 2: FRU
* Class 1: CE
* Class 0: FRC
*/
uint64_t afar2_overwrite[] = {
0
};
#endif /* SERRANO */
/*
* See UltraSPARC-IIIi PRM
* Class 2: UE, FRU, EDU, WDU, UCU, CPU
* Class 1: CE, FRC, EDC, WDC, UCC, CPC
*/
uint64_t esynd_overwrite[] = {
#if defined(SERRANO)
C_AFSR_ETS | C_AFSR_ETU |
#endif /* SERRANO */
0
};
/*
* Prioritized list of Error bits for BSYND (referred to as
* MSYND to share code with CHEETAH & CHEETAH_PLUS) overwrite.
* See UltraSPARC-IIIi PRM
* Class 3: ISAP
* Class 2: BP
* Class 1: WBP, IVPE
*/
uint64_t msynd_overwrite[] = {
0
};
/*
* change cpu speed bits -- new speed will be normal-speed/divisor.
*
* The Jalapeno memory controllers are required to drain outstanding
* memory transactions within 32 JBus clocks in order to be ready
* to enter Estar mode. In some corner cases however, that time
* fell short.
*
* A safe software solution is to force MCU to act like in Estar mode,
* then delay 1us (in ppm code) prior to assert J_CHNG_L signal.
* To reverse the effect, upon exiting Estar, software restores the
* MCU to its original state.
*/
/* ARGSUSED1 */
void
{
#if defined(JALAPENO) && defined(JALAPENO_ERRATA_85)
/*
* ASI Ecache flush in 1/2 or 1/32 speed mode can result
* is to force the CPU to full speed mode prior to using
* ASI Ecache flush opeartion to flush E$. Since we can't
* always use cross calls at the time of flushing E$, we
* cannot change other CPU speed. Hence, this workaround
* is applicable to uniprocessor configuration only and
* can't be used in multiprocessor configuration.
*
* Note that this workaround is activated only when the CPU
* has been fully initialized and its speed is lowered by the
* by setting jp_errata_85_enable to 0 and rebooting the
* system.
*/
if ((jp_errata_85_active == -1) &&
(divisor != JBUS_CONFIG_ECLK_1_DIV)) {
if (ncpus == 1)
jp_errata_85_active = 1;
else
jp_errata_85_active = 0;
}
int i;
/* We're only allowed to run the scrubbers at full speed */
for (i = 0; i < CACHE_SCRUBBER_COUNT; i++) {
chpr_scrubp->chsm_enable[i] =
}
}
#endif /* JALAPENO && JALAPENO_ERRATA_85 */
/*
* We're only interested in mcu_ctl_reg1 bit 26 and 25, of which
* the value will be stored in the lower half of a byte. The
* top bit of this byte is designated as a valid bit - 0 means
* invalid, 1 means valid.
*/
}
continue;
reg = get_jbus_config();
reg &= ~JBUS_CONFIG_ECLK_MASK;
(void) get_jbus_config();
/*
* MCU workaround, refer to Jalapeno spec, EnergyStar section
* for detail.
*/
/* Upon entering engery star mode, turn off extra MCU FSMs */
((divisor == JBUS_CONFIG_ECLK_2_DIV) ||
(divisor == JBUS_CONFIG_ECLK_32_DIV))) {
mreg = get_mcu_ctl_reg1();
if ((mreg & JP_MCU_FSM_MASK) != 0) {
mreg &= ~JP_MCU_FSM_MASK;
(void) get_mcu_ctl_reg1();
}
/* Upon exiting energy star mode, restore extra MCU FSMs */
} else if (divisor == JBUS_CONFIG_ECLK_1_DIV) {
mreg = get_mcu_ctl_reg1();
(void) get_mcu_ctl_reg1();
}
return;
}
/*
* We will reach here only if OBP and kernel don't agree on
* the speeds supported by the CPU.
*/
}
/*
* Cpu private initialization. This includes allocating the cpu_private
* data structure, initializing it, and initializing the scrubber for this
* cpu. This function calls cpu_init_ecache_scrub_dr to init the scrubber.
* We use kmem_cache_create for the cheetah private data structure because
* it needs to be allocated on a PAGESIZE (8192) byte boundary.
*/
void
{
int i;
/* LINTED: E_TRUE_LOGICAL_EXPR */
#if defined(SERRANO)
}
#else /* SERRANO */
}
#endif /* SERRANO */
/*
* If the ch_private_cache has not been created, create it.
*/
if (ch_private_cache == NULL) {
}
for (i = 0; i < CH_ERR_TL1_TLMAX; i++)
}
/*
* Clear the error state registers for this CPU.
* For Jalapeno, just clear the AFSR
*/
void
{
}
/*
* Update cpu_offline_set so the scrubber knows which cpus are offline
*/
/*ARGSUSED*/
int
{
switch (what) {
case CPU_ON:
case CPU_INIT:
break;
case CPU_OFF:
break;
default:
break;
}
return (0);
}