rock.c revision a6a911618075176ed839dbe7f7c90604d0954b46
/*
* 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
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/archsystm.h>
#include <sys/machparam.h>
#include <sys/machsystm.h>
#include <sys/elf_SPARC.h>
#include <sys/dditypes.h>
#include <sys/cpu_module.h>
#include <sys/prom_debug.h>
#include <sys/prom_plat.h>
#include <sys/sysmacros.h>
#include <sys/machtrap.h>
#include <sys/hypervisor_api.h>
#include <sys/rock_hypervisor_api.h>
#include <vm/hat_sfmmu.h>
char cpu_module_name[] = "SUNW,UltraSPARC-AT10";
static hsvc_info_t rock_tm_hsvc = {
HSVC_REV_1, /* HSVC rev num */
NULL, /* Private */
HSVC_GROUP_TM, /* Requested API Group */
ROCK_HSVC_MAJOR, /* Requested Major */
ROCK_HSVC_MINOR, /* Requested Minor */
cpu_module_name /* Module name */
};
#define MCOREID_MASK 0x1E
#define MCOREID_SHIFT 1
void
cpu_setup(void)
{
extern int cpc_has_overflow_intr;
int status;
/*
* The setup common to all CPU modules is done in cpu_setup_common
* routine.
*/
/*
* Rock's max nctxs is 64K. Set it accordingly.
*/
/*
* Rock I$ is non-coherent.
*/
#ifdef DEBUG
/*
* These should always be present on Rock
*/
if (cpu_hwcap_flags == 0)
#endif
if (use_page_coloring) {
do_pg_coloring = 1;
}
/*
* Rock generates hpriv performance event trap instead of pic overflow
* trap. To get the attention of the guest hv in-turn generates pic
* overflow trap. Therefore enable support for that.
*/
/*
* Enable 4M pages for OOB.
*/
/*
* hv_tm_enable is a part of TM group. We need to
* negotiate that API group before we can use it.
*/
"major: 0x%lx minor: 0x%lx group: 0x%x errno: %d",
}
}
/*
* Set the magic constants of the implementation.
*/
void
{
/*
* The Cache node is optional in MD. Therefore in case it
* does not exist, use hardcoded values.
*/
#ifdef DEBUG
/*
* ...that said, we do want this info to come from the MD.
*/
cpunode->ecache_associativity == 0) {
}
#endif
if (cpunode->ecache_size == 0)
if (cpunode->ecache_linesize == 0)
if (cpunode->ecache_associativity == 0)
}
void
{
if (pfn != -1) {
/* sparc needs 8-byte align */
}
}
}
void
{
/*
* The cpu_ipipe and cpu_fpu fields are initialized based on
* the execution unit sharing information from the MD. They
* default to the CPU id in the absence of such information.
*/
/*
* The cpu_chip field is initialized based on the information
* in the MD and assume that all cpus within a chip
* share the same L2 cache. If no such info is available, we
* set the cpu to CPU_CHIPID_INVALID.
*/
}
void
{
}
/*ARGSUSED*/
void
{
}
/*
* cpu_feature_init
*
* This function is called once per strand.
*/
void
cpu_feature_init(void)
{
/*
* Enable or disable for each cpu if hypervisor API is negotiated.
*/
if (hsvc_tm_available == B_TRUE)
}
/*
* Flush specified address range from I$ via hv_mem_iflush interface
* Note that the hypervisor interface expects physical address range
* and can flush less than the requested size.
*/
void
{
/*
* Do not clear the I-cache after bcopy.
* The default value is 0. This flag made be
*/
return;
if (!tba_taken_over)
/*
* Very early in boot, va_to_pa() will try to call back
* into OBP. Very *very* early in boot, this will fail
* because we haven't set up the OBP callback handler.
* (Without this check, kmdb boot will fail.)
*/
return;
/*
* Only flush the required length up to a PAGESIZE.
*/
/*
* Flush I$ up to the page bounday. This call should never
* fail. If it does, we panic the system as I$ may contain
* stale instructions, which can result in silent data
* corruption.
*/
}
}
}
/*
* There are no Hypervisor trapstat(1m) interfaces for Rock
* If trapstat(1m) wants to do its thing, it will have to
* take over all TLB miss handling.
*/
int
cpu_trapstat_conf(int cmd)
{
int status;
switch (cmd) {
case CPU_TSTATCONF_INIT:
case CPU_TSTATCONF_FINI:
case CPU_TSTATCONF_ENABLE:
case CPU_TSTATCONF_DISABLE:
break;
default:
break;
}
return (status);
}
/*ARGSUSED*/
void
{
}
#define MAX_PAGE_COLORS_SHIFT (5)
/*ARGSUSED*/
{
}
/*
* this macro rotates value "x" n steps to the right
* mask consists of "n + m" bits
* ASSERT(x < (1 << (n + m));
*/
/*
* on Rock, the hash cache index is calculated as follows:
* pa[47:43]^pa[42:38]^pa[37:33]^pa[32:28]^
* pa[27:23]^pa[22:18]^pa[17:13].pa[12:6]
* That is, every 5 bits is folded and XORd together. Page sizes
* differ by 3 bits, which is a factor of 8. This function computes
* the next sequential color by rotating by 3 steps within a field of 5 bits
* for every page size.
*/
void
{
(MAX_PAGE_COLORS_SHIFT - rot));
}
}
}
{
}
#if MMU_PAGE_SIZES > 8
#endif
{
}
/*ARGSUSED*/
{
return (color);
}
{
return (0);
}
/*ARGSUSED*/
{
do {
ceq_mask) == 0);
if (nsqn_color != base_sqn_color)
continue;
break;
wrap++;
return (cpfn);
}
void
{
int i;
for (i = 0; i < mmu_page_sizes; i++) {
}
/*
* initialise conversion table between page colors and
* sequential colors
*/
}
/*
* group colorequiv colors on Rock by low order bits of the color first
*/
void
{
if (colorequiv > 1) {
int i;
if (sv_a > 15)
sv_a = 15;
for (i = 0; i < MMU_PAGE_SIZES; i++) {
continue;
while ((colors >> a) == 0)
a--;
if (a > (colorequivszc[i] & 0xf) +
(colorequivszc[i] >> 4)) {
if (a <= nequiv_shades_log2[i]) {
colorequivszc[i] = (uchar_t)a;
} else {
colorequivszc[i] =
((a - nequiv_shades_log2[i]) << 4) |
}
}
}
}
}