/*
* 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.
*/
/*
* This file is through cpp before being used as
* an inline. It contains support routines used
* only by DR for the copy-rename sequence.
*/
#if defined(lint)
#else
#include "assym.h"
#include "drmach_offsets.h"
#endif /* lint */
#include <sys/asm_linkage.h>
#include <sys/privregs.h>
#include <sys/spitregs.h>
#include <sys/machthread.h>
#include <sys/cheetahregs.h>
#include <sys/sbd_ioctl.h>
#if !defined(lint)
/*
* turn off speculative mode to prevent unwanted memory access
* when we are in the FMEM loops
*/
#endif
#if defined(lint)
/*ARGSUSED*/
void
{ return; }
#else /* lint */
.align 8
/* turn off speculative mode */
/* read the critical region to get everything in the cache */
0:
/* clear L2_CTRL_UGE_TRAP error bit */
/* now tell the master CPU that we are ready */
1:
ba 5f
/*
* note that we branch to 5f, which branches right back to 2 here.
* The trick is that when that branch instruction has already been
* patched to a branch to itself - an infinite loop.
* The master thread will patch it back to "ba 2b" when it
* completes.
*/
/* Once we are back, we first check if there has been any
* L2_CTRL_UGE_TRAP errors, if so we have to fail the
* operation. This will cause a panic because the system
* is already in inconsistent state.
*/
2:
/* set error code and stat code */
3:
/* turn on speculative mode again */
ba 4f
.align 32
4:
.align 8
5:
/*
* busy wait will affect sibling strands so
* we put sleep instruction in the delay slot
*/
ba 2b
.word 0x81b01060
#endif /* lint */
#if defined(lint)
/*ARGSUSED*/
void
drmach_flush_icache(void)
{ return; }
#else /* lint */
.align 8
#endif
#if defined(lint)
/*ARGSUSED*/
int
{ return (0); }
#else /* lint */
.align 32
/* turn off speculative mode */
/* save locals to save area */
/* l7 is set only when FMEM cmd is issued to SCF */
/* read the critical region to put everything in the cache */
0:
ba 4f
/* we branch to 4f but eventually we branch back here to finish up */
1:
/*
* save some registers for debugging
* l0 - SCF_REG_BASE
* l1 - SCF_TD
* l2 - SCF_TD + 8
* l5 - DELAY
*/
/* Check for L2_CTRL_UGE_TRAP error */
2:
/* restore all locals */
/* turn on speculative mode */
ba 3f
.align 32
3:
/* return error code here */
/* clear L2_CTRL_UGE_TRAP error bit */
4:
5:
/* set up the register locations and parameters */
/* check if SCF is ONLINE */
ba 1b
/* check if SCF is busy */
ba 1b
/* clear STATUS bit */
6:
/* clear CMD_COMPLETE bit */
7:
8:
/*
* o1 points to SCFBASE.SCF_TDATA[0xe]
* l0 points to SCFBASE
* crticial->SCF_TD[0] = source board #
* crticial->SCF_TD[1] = target board #
* l1 = critical->SCF_TD[0 - 7]
* l2 = 0xffff
* o4 = critical->SCF_TD[8 - 15]
* o3 = (*o4) & 0xffff
/*
* Because there is no parity protection on the ebus
* we read the data back after the write to verify
* we write 2 bytes at a time.
* If the data read is not the same as data written
* we retry up to a limit of SCF_RETRY_CNT
*/
9:
ba 1b
7:
bne,a 9b
/* if we have reach TDATA+8, we switch to l1 */
/* XXX: Why we need 2 loops??? */
2:
bge,a 9b
/* if we reach TDATA, we are done */
/* read from SCF back to our buffer for debugging */
/* The following code conforms to the FMEM
sequence (4) as described in the Columbus2
logical spec section 4.6
*/
/* read from SCF SB INFO register */
/* If BUSY bit is set, abort */
bne 1b
/* Now tell SCF to do it */
/* 0x10A6 is the magic command */
/* read STATUS_READY bit and clear it only if it is set */
/* XXX: this STATUS_READY checking seems meaningless */
3:
/* check CMD_COMPLETE bit and clear */
4:
/* timeout delay checking */
5:
/* we are done or timed out */
6:
ba,a 1b
#endif /* lint */
#if defined(lint)
/*ARGSUSED*/
void
{ return; }
#else /* lint */
#endif /* lint */
#if defined(lint)
{
*x = y;
return (0);
}
#else /* lint */
#endif /* lint */
#if defined(lint)
void
{
}
#else /* lint */
#endif /* lint */
#if defined(lint)
{
return (0);
}
#else /* lint */
#endif /* lint */
#if defined(lint)
/*ARGSUSED*/
void
{}
#else /* lint */
0:
#endif /* lint */