Home | History | Annotate | Line # | Download | only in mips
      1  1.116  riastrad /*	$NetBSD: locore_mips3.S,v 1.116 2023/02/23 14:56:00 riastradh Exp $	*/
      2    1.2    castor 
      3    1.2    castor /*
      4    1.2    castor  * Copyright (c) 1997 Jonathan Stone (hereinafter referred to as the author)
      5    1.2    castor  * All rights reserved.
      6    1.2    castor  *
      7    1.2    castor  * Redistribution and use in source and binary forms, with or without
      8    1.2    castor  * modification, are permitted provided that the following conditions
      9    1.2    castor  * are met:
     10    1.2    castor  * 1. Redistributions of source code must retain the above copyright
     11    1.2    castor  *    notice, this list of conditions and the following disclaimer.
     12    1.2    castor  * 2. Redistributions in binary form must reproduce the above copyright
     13    1.2    castor  *    notice, this list of conditions and the following disclaimer in the
     14    1.2    castor  *    documentation and/or other materials provided with the distribution.
     15    1.2    castor  * 3. All advertising materials mentioning features or use of this software
     16    1.2    castor  *    must display the following acknowledgement:
     17    1.2    castor  *      This product includes software developed by Jonathan R. Stone for
     18    1.2    castor  *      the NetBSD Project.
     19    1.2    castor  * 4. The name of the author may not be used to endorse or promote products
     20    1.2    castor  *    derived from this software without specific prior written permission.
     21    1.2    castor  *
     22    1.2    castor  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
     23    1.2    castor  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24    1.2    castor  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25    1.2    castor  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE
     26    1.2    castor  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27    1.2    castor  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28    1.2    castor  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29    1.2    castor  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30    1.2    castor  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31    1.2    castor  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32    1.2    castor  * SUCH DAMAGE.
     33    1.2    castor  */
     34    1.2    castor 
     35    1.2    castor /*
     36    1.2    castor  * Copyright (c) 1992, 1993
     37    1.2    castor  *	The Regents of the University of California.  All rights reserved.
     38    1.2    castor  *
     39    1.2    castor  * This code is derived from software contributed to Berkeley by
     40    1.2    castor  * Digital Equipment Corporation and Ralph Campbell.
     41    1.2    castor  *
     42    1.2    castor  * Redistribution and use in source and binary forms, with or without
     43    1.2    castor  * modification, are permitted provided that the following conditions
     44    1.2    castor  * are met:
     45    1.2    castor  * 1. Redistributions of source code must retain the above copyright
     46    1.2    castor  *    notice, this list of conditions and the following disclaimer.
     47    1.2    castor  * 2. Redistributions in binary form must reproduce the above copyright
     48    1.2    castor  *    notice, this list of conditions and the following disclaimer in the
     49    1.2    castor  *    documentation and/or other materials provided with the distribution.
     50   1.86       agc  * 3. Neither the name of the University nor the names of its contributors
     51    1.2    castor  *    may be used to endorse or promote products derived from this software
     52    1.2    castor  *    without specific prior written permission.
     53    1.2    castor  *
     54    1.2    castor  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     55    1.2    castor  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     56    1.2    castor  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     57    1.2    castor  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     58    1.2    castor  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     59    1.2    castor  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     60    1.2    castor  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     61    1.2    castor  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     62    1.2    castor  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     63    1.2    castor  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     64    1.2    castor  * SUCH DAMAGE.
     65    1.2    castor  *
     66    1.2    castor  * Copyright (C) 1989 Digital Equipment Corporation.
     67    1.2    castor  * Permission to use, copy, modify, and distribute this software and
     68    1.2    castor  * its documentation for any purpose and without fee is hereby granted,
     69    1.2    castor  * provided that the above copyright notice appears in all copies.
     70    1.2    castor  * Digital Equipment Corporation makes no representations about the
     71    1.2    castor  * suitability of this software for any purpose.  It is provided "as is"
     72    1.2    castor  * without express or implied warranty.
     73    1.2    castor  *
     74    1.2    castor  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
     75    1.2    castor  *	v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
     76    1.2    castor  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
     77    1.2    castor  *	v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
     78    1.2    castor  * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
     79    1.2    castor  *	v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
     80    1.2    castor  *
     81    1.2    castor  *	@(#)locore.s	8.5 (Berkeley) 1/4/94
     82    1.2    castor  */
     83   1.29     soren #include "opt_cputype.h"
     84   1.18     soren #include "opt_ddb.h"
     85   1.82    simonb #include "opt_lockdebug.h"
     86   1.97      matt #include "opt_multiprocessor.h"
     87   1.68     lukem #include "opt_kgdb.h"
     88   1.18     soren 
     89   1.18     soren #include <sys/cdefs.h>
     90  1.100      matt #include <sys/endian.h>
     91   1.18     soren 
     92    1.2    castor #include <mips/asm.h>
     93    1.3  nisimura #include <mips/cpuregs.h>
     94    1.2    castor 
     95  1.116  riastrad RCSID("$NetBSD: locore_mips3.S,v 1.116 2023/02/23 14:56:00 riastradh Exp $")
     96  1.113     skrll 
     97    1.2    castor #include "assym.h"
     98    1.2    castor 
     99    1.2    castor /*
    100    1.2    castor  * XXX We need a cleaner way of handling the instruction hazards of
    101    1.2    castor  * the various processors.  Here are the relevant rules for the QED 52XX:
    102    1.2    castor  *	tlbw[ri]	-- two integer ops beforehand
    103    1.2    castor  *	tlbr		-- two integer ops beforehand
    104    1.2    castor  *	tlbp		-- two integer ops beforehand
    105    1.2    castor  *	mtc0	[PageMask,EntryHi,Cp0] -- two integer ops afterwards
    106    1.2    castor  *	changing JTLB	-- two integer ops afterwards
    107   1.32     soren  *	mtc0	[EPC,ErrorEPC,Status] -- two int ops afterwards before eret
    108    1.2    castor  *	config.k0	-- five int ops before kseg0, ckseg0 memref
    109    1.2    castor  *
    110    1.2    castor  * For the IDT R4000, some hazards are:
    111    1.2    castor  *	mtc0/mfc0	one integer op before and after
    112    1.2    castor  *	tlbp		-- one integer op afterwards
    113    1.2    castor  * Obvious solution is to take least common denominator.
    114    1.2    castor  */
    115    1.2    castor 
    116    1.2    castor /*
    117    1.2    castor  *============================================================================
    118    1.2    castor  *
    119   1.76    simonb  *  MIPS III ISA support, part 1: locore exception vectors.
    120   1.76    simonb  *  The following code is copied to the vector locations to which
    121   1.76    simonb  *  the CPU jumps in response to an exception or a TLB miss.
    122    1.2    castor  *
    123   1.76    simonb  *============================================================================
    124    1.2    castor  */
    125   1.76    simonb 	.set	noreorder
    126  1.110  macallan #if (__mips < 3) || __mips_o32
    127   1.76    simonb 	.set	mips3
    128  1.105      matt #endif
    129   1.74      shin 
    130   1.99      matt #ifdef _LP64
    131   1.99      matt #define	_MFC0	dmfc0
    132   1.99      matt #define	_MTC0	dmtc0
    133   1.99      matt #else
    134   1.99      matt #define	_MFC0	mfc0
    135   1.99      matt #define	_MTC0	mtc0
    136   1.99      matt #endif
    137   1.99      matt 
    138   1.74      shin 	.text
    139    1.2    castor 
    140    1.2    castor /*----------------------------------------------------------------------------
    141    1.2    castor  *
    142    1.2    castor  * mips3_wbflush --
    143    1.2    castor  *
    144    1.2    castor  *	Return when the write buffer is empty.
    145    1.2    castor  *
    146   1.76    simonb  *	Common for all MIPS3 and greater ISAs
    147    1.2    castor  *
    148    1.2    castor  * Results:
    149    1.2    castor  *	None.
    150    1.2    castor  *
    151    1.2    castor  * Side effects:
    152    1.2    castor  *	None.
    153    1.2    castor  *
    154    1.2    castor  *----------------------------------------------------------------------------
    155    1.2    castor  */
    156    1.2    castor LEAF(mips3_wbflush)
    157  1.101      matt XLEAF(loongson2_wbflush)
    158   1.76    simonb XLEAF(mips32_wbflush)
    159   1.98      matt XLEAF(mips32r2_wbflush)
    160   1.76    simonb XLEAF(mips64_wbflush)
    161   1.98      matt XLEAF(mips64r2_wbflush)
    162    1.2    castor 	nop
    163    1.2    castor 	sync
    164  1.102      matt 	jr	ra
    165   1.98      matt 	 nop
    166    1.2    castor END(mips3_wbflush)
    167    1.2    castor 
    168   1.67   thorpej 
    169   1.67   thorpej /*
    170   1.79    simonb  * mips_wait_idle:
    171   1.67   thorpej  *
    172   1.91      yamt  *	When no processes are on the runq, cpu_idle branches to
    173   1.91      yamt  *	mips_wait_idle to save power.
    174   1.67   thorpej  */
    175   1.79    simonb LEAF(mips_wait_idle)
    176   1.96      matt 	mfc0	v0, MIPS_COP_0_STATUS
    177   1.97      matt 	andi	v1, v0, MIPS_SR_INT_IE
    178  1.107      matt #if __mips >= 32
    179  1.107      matt 	teqi	v1, 0
    180  1.107      matt #else
    181   1.97      matt 	beqz	v1, 1f
    182   1.98      matt 	 nop
    183  1.107      matt #endif
    184   1.97      matt 	andi	v1, v0, MIPS_INT_MASK
    185  1.107      matt #if __mips >= 32
    186  1.107      matt 	teqi	v1, 0
    187  1.107      matt #else
    188   1.97      matt 	bnez	v1, 2f
    189   1.98      matt 	 nop
    190   1.97      matt 1:
    191   1.97      matt 	move	a1, v0
    192   1.97      matt 	PANIC("mips_wait_idle: interrupts disabled status=%#x")
    193  1.107      matt #endif
    194   1.96      matt 
    195   1.97      matt 2:	wait
    196   1.67   thorpej 	nop
    197   1.67   thorpej 	nop
    198   1.67   thorpej 	nop
    199  1.107      matt 	mfc0	v0, MIPS_COP_0_STATUS
    200  1.107      matt 	andi	v1, v0, MIPS_SR_INT_IE
    201  1.107      matt #if __mips >= 32
    202  1.107      matt 	teqi	v1, 0
    203  1.107      matt #else
    204  1.107      matt 	beqz	v1, 1b
    205  1.107      matt 	 nop
    206  1.107      matt #endif
    207  1.107      matt 	andi	v1, v0, MIPS_INT_MASK
    208  1.107      matt #if __mips >= 32
    209  1.107      matt 	teqi	v1, 0
    210  1.107      matt #else
    211  1.111     skrll 	beqz	v1, 1b
    212  1.107      matt 	 nop
    213  1.107      matt #endif
    214  1.102      matt 	jr	ra
    215   1.98      matt 	 nop
    216   1.79    simonb END(mips_wait_idle)
    217   1.76    simonb 
    218    1.2    castor /*
    219   1.96      matt  * uint32_t mips3_cp0_compare_read(void)
    220    1.2    castor  *
    221   1.76    simonb  *	Return the current value of the CP0 Compare register.
    222    1.2    castor  */
    223   1.76    simonb LEAF(mips3_cp0_compare_read)
    224   1.76    simonb 	mfc0	v0, MIPS_COP_0_COMPARE
    225  1.102      matt 	jr	ra
    226   1.98      matt 	 nop
    227   1.76    simonb END(mips3_cp0_compare_read)
    228   1.19  nisimura 
    229   1.22  nisimura /*
    230   1.96      matt  * void mips3_cp0_compare_write(uint32_t)
    231   1.22  nisimura  *
    232   1.76    simonb  *	Set the value of the CP0 Compare register.
    233   1.22  nisimura  */
    234   1.76    simonb LEAF(mips3_cp0_compare_write)
    235   1.76    simonb 	mtc0	a0, MIPS_COP_0_COMPARE
    236   1.98      matt 	JR_HB_RA
    237   1.76    simonb END(mips3_cp0_compare_write)
    238   1.76    simonb 
    239   1.22  nisimura /*
    240   1.96      matt  * uint32_t mips3_cp0_config_read(void)
    241   1.22  nisimura  *
    242   1.76    simonb  *	Return the current value of the CP0 Config register.
    243   1.22  nisimura  */
    244   1.76    simonb LEAF(mips3_cp0_config_read)
    245   1.76    simonb 	mfc0	v0, MIPS_COP_0_CONFIG
    246  1.102      matt 	jr	ra
    247   1.98      matt 	 nop
    248   1.76    simonb END(mips3_cp0_config_read)
    249   1.22  nisimura 
    250   1.22  nisimura /*
    251   1.96      matt  * void mips3_cp0_config_write(uint32_t)
    252   1.22  nisimura  *
    253   1.76    simonb  *	Set the value of the CP0 Config register.
    254   1.22  nisimura  */
    255   1.76    simonb LEAF(mips3_cp0_config_write)
    256   1.76    simonb 	mtc0	a0, MIPS_COP_0_CONFIG
    257   1.98      matt 	JR_HB_RA
    258   1.76    simonb END(mips3_cp0_config_write)
    259   1.57       cgd 
    260   1.98      matt #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0
    261   1.98      matt 	.set push
    262  1.106      matt #ifdef __mips_o32
    263  1.106      matt 	.set mips32
    264  1.106      matt #else
    265   1.99      matt 	.set mips64
    266   1.99      matt #endif
    267   1.57       cgd /*
    268   1.96      matt  * uint32_t mipsNN_cp0_config1_read(void)
    269   1.57       cgd  *
    270   1.76    simonb  *	Return the current value of the CP0 Config (Select 1) register.
    271   1.57       cgd  */
    272   1.76    simonb LEAF(mipsNN_cp0_config1_read)
    273   1.76    simonb 	mfc0	v0, MIPS_COP_0_CONFIG, 1
    274  1.102      matt 	jr	ra
    275   1.98      matt 	 nop
    276   1.76    simonb END(mipsNN_cp0_config1_read)
    277   1.36     soren 
    278   1.57       cgd /*
    279   1.96      matt  * uint32_t mipsNN_cp0_config1_write(uint32_t)
    280    1.2    castor  *
    281   1.98      matt  *	Set the current value of the CP0 Config (Select 1) register.
    282    1.2    castor  */
    283   1.76    simonb LEAF(mipsNN_cp0_config1_write)
    284   1.76    simonb 	mtc0	v0, MIPS_COP_0_CONFIG, 1
    285   1.98      matt 	JR_HB_RA
    286   1.76    simonb END(mipsNN_cp0_config1_write)
    287    1.2    castor 
    288   1.57       cgd /*
    289   1.96      matt  * uint32_t mipsNN_cp0_config2_read(void)
    290    1.2    castor  *
    291   1.76    simonb  *	Return the current value of the CP0 Config (Select 2) register.
    292   1.57       cgd  */
    293   1.76    simonb LEAF(mipsNN_cp0_config2_read)
    294   1.76    simonb 	mfc0	v0, MIPS_COP_0_CONFIG, 2
    295  1.102      matt 	jr	ra
    296   1.98      matt 	 nop
    297   1.76    simonb END(mipsNN_cp0_config2_read)
    298   1.57       cgd 
    299   1.57       cgd /*
    300   1.96      matt  * uint32_t mipsNN_cp0_config3_read(void)
    301    1.2    castor  *
    302   1.76    simonb  *	Return the current value of the CP0 Config (Select 3) register.
    303    1.2    castor  */
    304   1.76    simonb LEAF(mipsNN_cp0_config3_read)
    305   1.76    simonb 	mfc0	v0, MIPS_COP_0_CONFIG, 3
    306  1.102      matt 	jr	ra
    307   1.98      matt 	 nop
    308   1.76    simonb END(mipsNN_cp0_config3_read)
    309   1.98      matt 
    310   1.99      matt /*
    311  1.112      matt  * uint32_t mipsNN_cp0_config4_read(void)
    312  1.112      matt  *
    313  1.112      matt  *	Return the current value of the CP0 Config (Select 4) register.
    314  1.112      matt  */
    315  1.112      matt LEAF(mipsNN_cp0_config4_read)
    316  1.112      matt 	mfc0	v0, MIPS_COP_0_CONFIG, 4
    317  1.112      matt 	jr	ra
    318  1.112      matt 	 nop
    319  1.112      matt END(mipsNN_cp0_config4_read)
    320  1.112      matt 
    321  1.112      matt /*
    322  1.112      matt  * uint32_t mipsNN_cp0_config5_read(void)
    323  1.112      matt  *
    324  1.112      matt  *	Return the current value of the CP0 Config (Select 5) register.
    325  1.112      matt  */
    326  1.112      matt LEAF(mipsNN_cp0_config5_read)
    327  1.112      matt 	mfc0	v0, MIPS_COP_0_CONFIG, 5
    328  1.112      matt 	jr	ra
    329  1.112      matt 	 nop
    330  1.112      matt END(mipsNN_cp0_config5_read)
    331  1.112      matt 
    332  1.112      matt /*
    333  1.112      matt  * uint32_t mipsNN_cp0_config6_read(void)
    334  1.112      matt  *
    335  1.112      matt  *	Return the current value of the CP0 Config (Select 6) register.
    336  1.112      matt  */
    337  1.112      matt LEAF(mipsNN_cp0_config6_read)
    338  1.112      matt 	mfc0	v0, MIPS_COP_0_CONFIG, 6
    339  1.112      matt 	jr	ra
    340  1.112      matt 	 nop
    341  1.112      matt END(mipsNN_cp0_config6_read)
    342  1.112      matt 
    343  1.112      matt /*
    344  1.112      matt  * uint32_t mipsNN_cp0_config7_read(void)
    345  1.112      matt  *
    346  1.112      matt  *	Return the current value of the CP0 Config (Select 7) register.
    347  1.112      matt  */
    348  1.112      matt LEAF(mipsNN_cp0_config7_read)
    349  1.112      matt 	mfc0	v0, MIPS_COP_0_CONFIG, 7
    350  1.112      matt 	jr	ra
    351  1.112      matt 	 nop
    352  1.112      matt END(mipsNN_cp0_config7_read)
    353  1.112      matt 
    354  1.112      matt /*
    355   1.99      matt  * uintptr_t mipsNN_cp0_watchlo_read(u_int sel)
    356   1.99      matt  *
    357   1.99      matt  *	Return the current value of the selected CP0 Watchlo register.
    358   1.99      matt  */
    359   1.99      matt LEAF(mipsNN_cp0_watchlo_read)
    360   1.99      matt 	sll	a0, 2
    361   1.99      matt 	PTR_LA	t9, 1f
    362   1.99      matt 	PTR_ADDU t9, a0
    363   1.99      matt 	jr	t9
    364   1.99      matt 	 nop
    365   1.99      matt 1:
    366   1.99      matt 	jr	ra
    367   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 0
    368   1.99      matt 	jr	ra
    369   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 1
    370   1.99      matt 	jr	ra
    371   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 2
    372   1.99      matt 	jr	ra
    373   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 3
    374   1.99      matt 	jr	ra
    375   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 4
    376   1.99      matt 	jr	ra
    377   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 5
    378   1.99      matt 	jr	ra
    379   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 6
    380   1.99      matt 	jr	ra
    381   1.99      matt 	 _MFC0	v0, MIPS_COP_0_WATCH_LO, 7
    382   1.99      matt END(mipsNN_cp0_watchlo_read)
    383   1.99      matt 
    384   1.99      matt /*
    385   1.99      matt  * void mipsNN_cp0_watchlo_write(u_int sel, uintptr_t val)
    386   1.99      matt  *
    387   1.99      matt  *	Set the current value of the selected CP0 WatchLo register.
    388   1.99      matt  */
    389   1.99      matt LEAF(mipsNN_cp0_watchlo_write)
    390   1.99      matt 	sll	a0, 2
    391   1.99      matt 	PTR_LA	t9, 1f
    392   1.99      matt 	PTR_ADDU t9, a0
    393   1.99      matt 	jr	t9
    394   1.99      matt 	 nop
    395   1.99      matt 1:
    396   1.99      matt 	jr	ra
    397   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 0
    398   1.99      matt 	jr	ra
    399   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 1
    400   1.99      matt 	jr	ra
    401   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 2
    402   1.99      matt 	jr	ra
    403   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 3
    404   1.99      matt 	jr	ra
    405   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 4
    406   1.99      matt 	jr	ra
    407   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 5
    408   1.99      matt 	jr	ra
    409   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 6
    410   1.99      matt 	jr	ra
    411   1.99      matt 	 _MTC0	a1, MIPS_COP_0_WATCH_LO, 7
    412   1.99      matt END(mipsNN_cp0_watchlo_write)
    413   1.99      matt 
    414   1.99      matt /*
    415   1.99      matt  * uint32_t mipsNN_cp0_watchhi_read(u_int sel)
    416   1.99      matt  *
    417   1.99      matt  *	Return the current value of the selected CP0 WatchHi register.
    418   1.99      matt  */
    419   1.99      matt LEAF(mipsNN_cp0_watchhi_read)
    420   1.99      matt 	sll	a0, 2
    421   1.99      matt 	PTR_LA	t9, 1f
    422   1.99      matt 	PTR_ADDU t9, a0
    423   1.99      matt 	jr	t9
    424   1.99      matt 	 nop
    425   1.99      matt 1:
    426   1.99      matt 	jr	ra
    427   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 0
    428   1.99      matt 	jr	ra
    429   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 1
    430   1.99      matt 	jr	ra
    431   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 2
    432   1.99      matt 	jr	ra
    433   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 3
    434   1.99      matt 	jr	ra
    435   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 4
    436   1.99      matt 	jr	ra
    437   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 5
    438   1.99      matt 	jr	ra
    439   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 6
    440   1.99      matt 	jr	ra
    441   1.99      matt 	 mfc0	v0, MIPS_COP_0_WATCH_HI, 7
    442   1.99      matt END(mipsNN_cp0_watchhi_read)
    443   1.99      matt 
    444   1.99      matt /*
    445   1.99      matt  * void mipsNN_cp0_watchhi_write(u_int sel, uint32_t val)
    446   1.99      matt  *
    447   1.99      matt  *	Set the current value of the selected CP0 WatchHi register.
    448   1.99      matt  */
    449   1.99      matt LEAF(mipsNN_cp0_watchhi_write)
    450   1.99      matt 	sll	a0, 2
    451   1.99      matt 	PTR_LA	t9, 1f
    452   1.99      matt 	PTR_ADDU t9, a0
    453   1.99      matt 	jr	t9
    454   1.99      matt 	 nop
    455   1.99      matt 1:
    456   1.99      matt 	jr	ra
    457   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 0
    458   1.99      matt 	jr	ra
    459   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 1
    460   1.99      matt 	jr	ra
    461   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 2
    462   1.99      matt 	jr	ra
    463   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 3
    464   1.99      matt 	jr	ra
    465   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 4
    466   1.99      matt 	jr	ra
    467   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 5
    468   1.99      matt 	jr	ra
    469   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 6
    470   1.99      matt 	jr	ra
    471   1.99      matt 	 mtc0	a1, MIPS_COP_0_WATCH_HI, 7
    472   1.99      matt END(mipsNN_cp0_watchhi_write)
    473   1.99      matt 
    474  1.103      matt /*
    475  1.103      matt  * void mipsNN_cp0_ebase_read(void *);
    476  1.103      matt  *	Get the value of the CP0 EBASE (PRID, select 1) register.
    477  1.103      matt  */
    478  1.103      matt LEAF(mipsNN_cp0_ebase_read)
    479  1.103      matt 	jr	ra
    480  1.108      matt 	 mfc0	v0, MIPS_COP_0_EBASE
    481  1.103      matt END(mipsNN_cp0_ebase_read)
    482  1.103      matt 
    483  1.103      matt /*
    484  1.103      matt  * void mipsNN_cp0_ebase_write(void *);
    485  1.103      matt  *	Set the value of the CP0 EBASE (PRID, select 1) register.
    486  1.103      matt  */
    487  1.103      matt LEAF(mipsNN_cp0_ebase_write)
    488  1.103      matt 	and	v0, v0, 0x1ff
    489  1.103      matt 	xor	v0, v0, a0
    490  1.103      matt 	jr	ra
    491  1.108      matt 	 mtc0	v0, MIPS_COP_0_EBASE
    492  1.103      matt END(mipsNN_cp0_ebase_write)
    493  1.103      matt 
    494   1.98      matt #if (MIPS32R2 + MIPS64R2) > 0
    495   1.98      matt /*
    496  1.115    simonb  * uint32_t mipsNN_cp0_rdhwr_cpunum(void);
    497  1.115    simonb  *	Set the value of the CP0 HWRENA register.
    498  1.115    simonb  */
    499  1.115    simonb LEAF(mipsNN_cp0_rdhwr_cpunum)
    500  1.115    simonb 	.set push
    501  1.115    simonb #ifdef __mips_o32
    502  1.115    simonb 	.set mips32r2
    503  1.115    simonb #else
    504  1.115    simonb 	.set mips64r2
    505  1.115    simonb #endif
    506  1.115    simonb 	jr	ra
    507  1.115    simonb 	 rdhwr	v0, MIPS_HWR_CPUNUM
    508  1.115    simonb 	.set pop
    509  1.115    simonb END(mipsNN_cp0_rdhwr_cpunum)
    510  1.115    simonb 
    511  1.115    simonb /*
    512  1.108      matt  * void mipsNN_cp0_hwrena_write(void *);
    513  1.108      matt  *	Set the value of the CP0 HWRENA register.
    514   1.98      matt  */
    515   1.98      matt LEAF(mipsNN_cp0_hwrena_write)
    516  1.102      matt 	jr	ra
    517   1.99      matt 	 mtc0	a0, MIPS_COP_0_HWRENA
    518   1.98      matt END(mipsNN_cp0_hwrena_write)
    519   1.98      matt 
    520   1.98      matt /*
    521   1.98      matt  * void mipsNN_cp0_userlocal_write(void *);
    522   1.98      matt  *	Set the value of the CP0 USERLOCAL (TLB_CONTEXT, select 2) register.
    523   1.98      matt  */
    524   1.98      matt LEAF(mipsNN_cp0_userlocal_write)
    525  1.102      matt 	jr	ra
    526  1.108      matt 	 _MTC0	a0, MIPS_COP_0_USERLOCAL
    527   1.98      matt END(mipsNN_cp0_userlocal_write)
    528   1.98      matt #endif /* (MIPS32R2 + MIPS64R2) > 0 */
    529   1.98      matt 	.set	pop
    530   1.98      matt #endif /* (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 */
    531    1.2    castor 
    532    1.2    castor /*
    533   1.96      matt  * uint32_t mips3_cp0_count_read(void)
    534    1.2    castor  *
    535   1.57       cgd  *	Return the current value of the CP0 Count register.
    536    1.2    castor  */
    537   1.57       cgd LEAF(mips3_cp0_count_read)
    538   1.57       cgd 	mfc0	v0, MIPS_COP_0_COUNT
    539  1.102      matt 	jr	ra
    540   1.98      matt 	 nop
    541   1.57       cgd END(mips3_cp0_count_read)
    542   1.97      matt WEAK_ALIAS(cpu_counter32, mips3_cp0_count_read)
    543    1.2    castor 
    544    1.2    castor /*
    545   1.96      matt  * void mips3_cp0_count_write(uint32_t)
    546    1.2    castor  *
    547   1.57       cgd  *	Set the value of the CP0 Count register.
    548    1.2    castor  */
    549   1.57       cgd LEAF(mips3_cp0_count_write)
    550   1.57       cgd 	mtc0	a0, MIPS_COP_0_COUNT
    551   1.98      matt 	JR_HB_RA
    552   1.57       cgd END(mips3_cp0_count_write)
    553   1.57       cgd 
    554   1.57       cgd /*
    555   1.96      matt  * uint32_t mips3_cp0_wired_read(void)
    556   1.57       cgd  *
    557   1.57       cgd  *	Return the current value of the CP0 Wired register.
    558   1.57       cgd  */
    559   1.57       cgd LEAF(mips3_cp0_wired_read)
    560   1.57       cgd 	mfc0	v0, MIPS_COP_0_TLB_WIRED
    561  1.102      matt 	jr	ra
    562   1.98      matt 	 nop
    563   1.57       cgd END(mips3_cp0_wired_read)
    564    1.2    castor 
    565   1.57       cgd /*
    566   1.96      matt  * void mips3_cp0_wired_write(uint32_t)
    567   1.57       cgd  *
    568   1.57       cgd  *	Set the value of the CP0 Wired register.
    569   1.57       cgd  */
    570   1.57       cgd LEAF(mips3_cp0_wired_write)
    571   1.57       cgd 	mtc0	a0, MIPS_COP_0_TLB_WIRED
    572   1.98      matt 	JR_HB_RA
    573   1.57       cgd END(mips3_cp0_wired_write)
    574   1.55       cgd 
    575   1.87   tsutsui /*
    576   1.96      matt  * void mips3_cp0_pg_mask_write(uint32_t)
    577   1.87   tsutsui  *
    578   1.87   tsutsui  *	Set the value of the CP0 PG_MASK register.
    579   1.87   tsutsui  */
    580   1.87   tsutsui LEAF(mips3_cp0_pg_mask_write)
    581   1.87   tsutsui 	mtc0	a0, MIPS_COP_0_TLB_PG_MASK
    582   1.98      matt 	JR_HB_RA
    583   1.87   tsutsui END(mips3_cp0_pg_mask_write)
    584   1.87   tsutsui 
    585  1.106      matt #if __mips != 32
    586   1.55       cgd LEAF(mips3_ld)
    587   1.96      matt #if defined(__mips_o32)
    588  1.112      matt #if (MIPS64R2) > 0
    589  1.112      matt 	di	t0
    590  1.112      matt #else
    591   1.92  uebayasi 	mfc0	t0, MIPS_COP_0_STATUS		# turn off interrupts
    592   1.55       cgd 	and	t1, t0, ~(MIPS_SR_INT_IE)
    593   1.55       cgd 	mtc0	t1, MIPS_COP_0_STATUS
    594  1.112      matt #endif
    595   1.71       uch 	COP0_SYNC
    596   1.55       cgd 
    597   1.55       cgd 	ld	v0, 0(a0)
    598   1.55       cgd #if _BYTE_ORDER == _BIG_ENDIAN
    599   1.76    simonb 	dsll	v1, v0, 32
    600   1.76    simonb 	dsra	v1, v1, 32			# low word in v1
    601   1.55       cgd #else
    602   1.55       cgd 	dsra	v1, v0, 32			# high word in v1
    603   1.76    simonb 	dsll	v0, v0, 32
    604  1.112      matt #endif
    605   1.76    simonb 	dsra	v0, v0, 32			# low word in v0
    606   1.55       cgd 
    607   1.55       cgd 	mtc0	t0, MIPS_COP_0_STATUS		# restore intr status.
    608   1.98      matt 	JR_HB_RA
    609   1.96      matt #else /* !__mips_o32 */
    610   1.98      matt 	jr	ra
    611  1.112      matt 	 ld	v0, 0(a0)
    612   1.96      matt #endif /* !__mips_o32 */
    613   1.55       cgd END(mips3_ld)
    614   1.55       cgd 
    615   1.55       cgd LEAF(mips3_sd)
    616   1.96      matt #if defined(__mips_o32)
    617  1.112      matt #if (MIPS64R2) > 0
    618  1.112      matt 	di	t0
    619  1.112      matt #else
    620   1.92  uebayasi 	mfc0	t0, MIPS_COP_0_STATUS		# turn off interrupts
    621   1.55       cgd 	and	t1, t0, ~(MIPS_SR_INT_IE)
    622   1.55       cgd 	mtc0	t1, MIPS_COP_0_STATUS
    623  1.112      matt #endif
    624   1.71       uch 	COP0_SYNC
    625   1.55       cgd 
    626  1.112      matt 	dsll	a2, a2, 32			# high word in a2
    627   1.55       cgd #if _BYTE_ORDER == _BIG_ENDIAN
    628   1.55       cgd 	dsll	a3, a3, 32			# low word in a3
    629   1.55       cgd 	dsrl	a3, a3, 32
    630   1.55       cgd #else
    631   1.55       cgd 	dsrl	a2, a2, 32
    632   1.55       cgd 	dsll	a3, a3, 32			# high word in a3
    633   1.55       cgd #endif
    634   1.55       cgd 	or	a1, a2, a3
    635   1.55       cgd 	sd	a1, 0(a0)
    636   1.55       cgd 
    637   1.55       cgd 	mtc0	t0, MIPS_COP_0_STATUS		# restore intr status.
    638   1.98      matt 	JR_HB_RA
    639   1.96      matt #else /* !__mips_o32 */
    640   1.98      matt 	jr	ra
    641  1.112      matt 	 sd	a1, 0(a0)
    642   1.96      matt #endif /* !__mips_o32 */
    643   1.55       cgd END(mips3_sd)
    644    1.2    castor 
    645    1.2    castor /*
    646   1.76    simonb  * int badaddr64(uint64_t addr, int len)
    647   1.76    simonb  * See if access to addr with a len type instruction causes a machine check.
    648   1.76    simonb  * len is length of access in bytes (can be 1, 2, 4, or 8).
    649   1.76    simonb  */
    650   1.76    simonb LEAF(badaddr64)
    651   1.96      matt 	PTR_L	v1, L_PCB(MIPS_CURLWP)
    652   1.96      matt 	PTR_LA	v0, _C_LABEL(baderr64)
    653   1.76    simonb 
    654  1.112      matt #ifdef __mips_o32
    655   1.76    simonb 	/* Enable KX */
    656   1.76    simonb 	mfc0	t0, MIPS_COP_0_STATUS
    657   1.76    simonb 	or	t1, t0, MIPS3_SR_KX
    658   1.97      matt 	and	t2, t0, MIPS_SR_INT_IE	# disable interrupts
    659   1.97      matt 	xor	t1, t2
    660   1.76    simonb 	mtc0	t1, MIPS_COP_0_STATUS
    661   1.84    simonb 	COP0_SYNC
    662    1.2    castor 
    663   1.97      matt #ifdef __MIPSEB__
    664   1.97      matt 	dsll	a0, a0, 32	# MSW
    665   1.97      matt 	dsll	a1, a1, 32	# LSW
    666   1.97      matt 	dsrl	a1, a1, 32
    667   1.97      matt #else
    668   1.97      matt 	dsll	a1, a1, 32	# MSW
    669   1.97      matt 	dsll	a0, a0, 32	# LSW
    670   1.97      matt 	dsrl	a0, a0, 32
    671   1.97      matt #endif
    672   1.97      matt 	or	a0, a1		# combine
    673   1.97      matt 	move	a1, a2		# move up length argument
    674   1.97      matt #endif /* __mips_o32 */
    675   1.97      matt 
    676   1.96      matt 	bne	a1, 1, 2f
    677   1.98      matt 	 PTR_S	v0, PCB_ONFAULT(v1)
    678   1.76    simonb 	b	9f
    679   1.97      matt 	 lbu	v0, (a0)
    680   1.76    simonb 2:
    681   1.96      matt 	bne	a1, 2, 4f
    682   1.98      matt 	 nop
    683   1.76    simonb 	b	9f
    684   1.97      matt 	 lhu	v0, (a0)
    685   1.76    simonb 4:
    686   1.96      matt 	bne	a1, 4, 8f
    687   1.98      matt 	 nop
    688   1.76    simonb 	b	9f
    689   1.97      matt 	 INT_L	v0, (a0)
    690   1.76    simonb 8:
    691   1.96      matt 	REG_L	v0, (a0)
    692   1.76    simonb 9:
    693   1.97      matt 	sync
    694  1.112      matt #ifdef __mips_o32
    695   1.76    simonb 	mtc0	t0, MIPS_COP_0_STATUS           # Restore KX
    696   1.84    simonb 	COP0_SYNC
    697  1.112      matt #endif
    698   1.96      matt 	PTR_S	zero, PCB_ONFAULT(v1)
    699  1.102      matt 	jr	ra
    700   1.97      matt 	 move	v0, zero			# made it w/o errors
    701   1.76    simonb END(badaddr64)
    702   1.76    simonb 
    703   1.76    simonb LEAF(baderr64)
    704  1.112      matt #ifdef __mips_o32
    705   1.76    simonb 	mtc0	t0, MIPS_COP_0_STATUS		# Restore KX
    706   1.84    simonb 	COP0_SYNC
    707  1.112      matt #endif
    708   1.96      matt 	PTR_S	zero, PCB_ONFAULT(v1)
    709  1.102      matt 	jr	ra
    710   1.96      matt 	 li	v0, -1
    711   1.76    simonb END(baderr64)
    712   1.97      matt 
    713   1.97      matt /*
    714   1.97      matt  * uint64_t mips3_cp0_tlb_entry_hi_probe(void);
    715   1.97      matt  *
    716   1.97      matt  * Write 1s to the VPN and ASID fields of Entry_Hi0 to see how many VA bits
    717   1.97      matt  * and ASID bits are implemented.  Assumes that interrupts are disabled.
    718   1.97      matt  */
    719   1.97      matt LEAF(mips3_cp0_tlb_entry_hi_probe)
    720   1.97      matt 	dmfc0	t0, MIPS_COP_0_TLB_HI
    721   1.97      matt 	li	v0, -1		/* all 1s */
    722  1.105      matt #if defined(__mips_isa_rev) && __mips_isa_rev >= 2
    723  1.105      matt 	dinsu	v0, zero, 62, 2
    724  1.105      matt #else
    725   1.97      matt 	dsll	v0, v0, 2	/* except the top 2 */
    726   1.97      matt 	dsrl	v0, v0, 2
    727  1.105      matt #endif
    728   1.97      matt 	dmtc0	v0, MIPS_COP_0_TLB_HI
    729   1.97      matt 	COP0_SYNC
    730   1.97      matt 	dmfc0	v0, MIPS_COP_0_TLB_HI
    731   1.97      matt 	dmtc0	t0, MIPS_COP_0_TLB_HI
    732   1.97      matt 	COP0_SYNC
    733   1.97      matt 	nop
    734   1.97      matt #ifdef __mips_o32
    735   1.97      matt 	nop
    736   1.97      matt #if BYTE_ORDER == BIG_ENDIAN
    737   1.97      matt 	srl	v1, v0, 0
    738   1.97      matt 	dsra	v0, v0, 32
    739   1.76    simonb #endif
    740   1.97      matt #if BYTE_ORDER == LITTLE_ENDIAN
    741   1.97      matt 	dsra	v1, v0, 32
    742   1.97      matt 	srl	v0, v0, 0
    743   1.97      matt #endif
    744   1.97      matt #endif /* __mips_o32 */
    745  1.102      matt 	jr	ra
    746   1.97      matt 	 nop
    747   1.97      matt END(mips3_cp0_tlb_entry_hi_probe)
    748  1.112      matt #endif /* __mips != 32 */
    749   1.97      matt 
    750   1.97      matt /*
    751   1.97      matt  * uint64_t mips3_cp0_tlb_entry_lo_probe(void);
    752   1.97      matt  *
    753   1.97      matt  * Write 1s to the PFN field of Entry_Lo0 to see how many
    754   1.97      matt  * PA bits are implemented.  Assumes that interrupts are disabled.
    755   1.97      matt  */
    756   1.97      matt LEAF(mips3_cp0_tlb_entry_lo_probe)
    757   1.97      matt 	dmfc0	t0, MIPS_COP_0_TLB_LO0
    758   1.97      matt 	li	v0, -64		/* all 1s except low 6 bits */
    759   1.97      matt 	dmtc0	v0, MIPS_COP_0_TLB_LO0
    760   1.97      matt 	COP0_SYNC
    761   1.97      matt 	dmfc0	v0, MIPS_COP_0_TLB_LO0
    762   1.97      matt 	dmtc0	t0, MIPS_COP_0_TLB_LO0
    763   1.97      matt 	COP0_SYNC
    764   1.97      matt #ifdef __mips_o32
    765   1.97      matt #if BYTE_ORDER == BIG_ENDIAN
    766   1.97      matt 	srl	v1, v0, 0
    767   1.97      matt 	dsra	v0, v0, 32
    768   1.97      matt #endif
    769   1.97      matt #if BYTE_ORDER == LITTLE_ENDIAN
    770   1.97      matt 	dsra	v1, v0, 32
    771   1.97      matt 	srl	v0, v0, 0
    772   1.97      matt #endif
    773   1.97      matt #endif /* __mips_o32 */
    774  1.102      matt 	jr	ra
    775   1.97      matt 	 nop
    776   1.97      matt END(mips3_cp0_tlb_entry_lo_probe)
    777   1.97      matt 
    778   1.97      matt /*
    779   1.97      matt  * uint32_t mips3_cp0_tlb_page_mask_probe(void);
    780   1.97      matt  *
    781   1.97      matt  * Write 1s to the RPN field of Entry_Lo0 to see how many PA bits are implemented.
    782   1.97      matt  * Assumes that interrupts are disabled.
    783   1.97      matt  */
    784   1.97      matt LEAF(mips3_cp0_tlb_page_mask_probe)
    785   1.97      matt 	mfc0	t0, MIPS_COP_0_TLB_PG_MASK
    786   1.97      matt 	lui	v0, 0xffff
    787   1.97      matt 	srl	v0, v0, 3
    788   1.97      matt 	mtc0	v0, MIPS_COP_0_TLB_PG_MASK
    789   1.97      matt 	COP0_SYNC
    790   1.97      matt 	mfc0	v0, MIPS_COP_0_TLB_PG_MASK
    791   1.97      matt 	mtc0	t0, MIPS_COP_0_TLB_PG_MASK
    792   1.98      matt 	JR_HB_RA
    793   1.97      matt END(mips3_cp0_tlb_page_mask_probe)
    794   1.97      matt 
    795   1.97      matt #ifdef MULTIPROCESSOR
    796   1.97      matt /*
    797  1.103      matt  * MD code calls/jumps to this with the pointer to this CPU's cpu_info in a1,
    798  1.103      matt  * sp set to ci->ci_data.cpu_idlelwp->l_md.md_utf.  gp will be overridden so
    799   1.97      matt  * 0 can be supplied if needed.  (This happens to match what CFE wants)
    800   1.97      matt  */
    801   1.97      matt NESTED_NOPROFILE(cpu_trampoline, 0, ra)
    802   1.97      matt 	/*
    803   1.97      matt 	 * We act as the idle lwp so make it CURLWP.  When know
    804   1.97      matt 	 * that the cpu_info is a KSEG0 address.
    805   1.97      matt 	 */
    806   1.97      matt 	move	a0, a1
    807  1.103      matt 	// Loop until idlelwp is filled in.
    808  1.103      matt 1:	PTR_L	MIPS_CURLWP, CPU_INFO_IDLELWP(a0)
    809   1.97      matt 	nop
    810  1.103      matt 	beqz	MIPS_CURLWP, 1b
    811  1.103      matt 	 nop
    812  1.116  riastrad 	/*
    813  1.116  riastrad 	 * No membar needed because we're not switching from a
    814  1.116  riastrad 	 * previous lwp, and the idle lwp we're switching to can't be
    815  1.116  riastrad 	 * holding locks already; see cpu_switchto.
    816  1.116  riastrad 	 */
    817   1.97      matt 	PTR_S	MIPS_CURLWP, CPU_INFO_CURLWP(a0)
    818   1.97      matt 
    819   1.97      matt #ifdef _LP64
    820   1.97      matt 	li	v0, MIPS_SR_KX | MIPS_SR_UX	# allow 64bit addressing
    821  1.112      matt #elif defined(__mips_n32)
    822  1.112      matt 	li	v0, MIPS_SR_KX			# allow 64bit kernel addressing
    823   1.97      matt #else
    824   1.97      matt 	li	v0, 0
    825   1.97      matt #endif
    826   1.97      matt 	mtc0	v0, MIPS_COP_0_STATUS		# reset to known state
    827   1.97      matt 	COP0_SYNC
    828   1.97      matt 
    829  1.104      matt 	PTR_L	sp, L_MD_UTF(MIPS_CURLWP)	# fetch KSP
    830  1.104      matt 
    831   1.97      matt 	/*
    832   1.97      matt 	 * Indicate that no one has called us.
    833   1.97      matt 	 */
    834   1.97      matt 	move	ra, zero
    835   1.97      matt 	REG_S	ra, CALLFRAME_RA(sp)
    836   1.97      matt 
    837   1.97      matt #ifdef __GP_SUPPORT__
    838   1.97      matt 	/*
    839   1.97      matt 	 * New execution constant needs GP to be loaded.
    840   1.97      matt 	 */
    841   1.97      matt 	PTR_LA	gp, _C_LABEL(_gp)
    842   1.97      matt #endif
    843   1.97      matt 
    844  1.104      matt #if 0
    845  1.104      matt 	LONG_L	t0, CPU_INFO_FLAGS(a0)
    846  1.104      matt 	or	t0, t0, CPUF_PRESENT
    847  1.104      matt 	LONG_S	t0, CPU_INFO_FLAGS(a0)
    848  1.104      matt 	sync
    849  1.104      matt #endif
    850  1.104      matt 
    851   1.97      matt 	/*
    852   1.97      matt 	 * and off we go.
    853   1.97      matt 	 */
    854   1.97      matt 	j	_C_LABEL(cpu_hatch)		# does everything
    855   1.97      matt 	 nop
    856   1.97      matt END(cpu_trampoline)
    857   1.97      matt #endif /* MULTIPROCESSOR */
    858