Home | History | Annotate | Line # | Download | only in oea
ofw_subr.S revision 1.2
      1  1.2  matt /*	$NetBSD: ofw_subr.S,v 1.2 2003/02/13 15:02:49 matt Exp $	*/
      2  1.1  matt 
      3  1.1  matt /*
      4  1.1  matt  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
      5  1.1  matt  * Copyright (C) 1995, 1996 TooLs GmbH.
      6  1.1  matt  * All rights reserved.
      7  1.1  matt  *
      8  1.1  matt  * Redistribution and use in source and binary forms, with or without
      9  1.1  matt  * modification, are permitted provided that the following conditions
     10  1.1  matt  * are met:
     11  1.1  matt  * 1. Redistributions of source code must retain the above copyright
     12  1.1  matt  *    notice, this list of conditions and the following disclaimer.
     13  1.1  matt  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  matt  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  matt  *    documentation and/or other materials provided with the distribution.
     16  1.1  matt  * 3. All advertising materials mentioning features or use of this software
     17  1.1  matt  *    must display the following acknowledgement:
     18  1.1  matt  *	This product includes software developed by TooLs GmbH.
     19  1.1  matt  * 4. The name of TooLs GmbH may not be used to endorse or promote products
     20  1.1  matt  *    derived from this software without specific prior written permission.
     21  1.1  matt  *
     22  1.1  matt  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
     23  1.1  matt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  1.1  matt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  1.1  matt  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26  1.1  matt  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     27  1.1  matt  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     28  1.1  matt  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     29  1.1  matt  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     30  1.1  matt  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     31  1.1  matt  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  1.1  matt  */
     33  1.1  matt 
     34  1.1  matt 
     35  1.1  matt 	.local	firmstk
     36  1.1  matt 	.local	openfirmware_entry
     37  1.1  matt 	.local	ofwsrsave
     38  1.1  matt 	.local	OF_buffer
     39  1.1  matt 
     40  1.1  matt 	.data
     41  1.1  matt GLOBAL(ofmsr)
     42  1.1  matt 	.long	0,0,0,0,0		/* msr & sprg[0-3] used in OF */
     43  1.1  matt 
     44  1.1  matt GLOBAL(ofwsprg0save)
     45  1.1  matt 	.long	0
     46  1.1  matt 
     47  1.1  matt 	.comm	firmstk,NBPG,8
     48  1.1  matt 	.comm	OF_buffer,NBPG,4
     49  1.1  matt 	.comm	openfirmware_entry,4,4	/* openfirmware entry point */
     50  1.1  matt 	.comm	ofwsrsave,64,4		/* openfirmware SR savearea */
     51  1.1  matt 
     52  1.1  matt /*
     53  1.1  matt  * Called by start to save the initial OFW state so we can restore it
     54  1.1  matt  * when call back to OFW.
     55  1.1  matt  */
     56  1.1  matt ENTRY_NOPROFILE(ofwinit)
     57  1.1  matt #ifdef	FIRMWORKSBUGS
     58  1.1  matt 	mfmsr	0
     59  1.1  matt 	andi.	0,0,PSL_IR|PSL_DR
     60  1.1  matt 	beq	1f
     61  1.1  matt 
     62  1.1  matt 	mflr	30
     63  1.1  matt 	bl	_C_LABEL(ofwr_init)
     64  1.1  matt 	mtlr	30
     65  1.1  matt 1:
     66  1.1  matt #endif
     67  1.1  matt 	lis	8,openfirmware_entry@ha
     68  1.1  matt 	stw	5,openfirmware_entry@l(8) /* save client interface handler*/
     69  1.1  matt 
     70  1.1  matt 	mfmsr	0
     71  1.1  matt 	lis	9,ofmsr@ha
     72  1.1  matt 	stwu	0,ofmsr@l(9)		/* save initial MSR value */
     73  1.1  matt 
     74  1.1  matt         mfsprg  0,0			/* save SPRGs */
     75  1.1  matt        	stwu	0,4(9)
     76  1.1  matt         mfsprg  0,1
     77  1.1  matt        	stwu	0,4(9)
     78  1.1  matt         mfsprg  0,2
     79  1.1  matt        	stwu	0,4(9)
     80  1.1  matt         mfsprg  0,3
     81  1.1  matt        	stw	0,4(9)
     82  1.1  matt 
     83  1.2  matt 	lis	8,OF_buffer@ha
     84  1.2  matt 	addi	8,8,OF_buffer@l
     85  1.1  matt 	lis	9,_C_LABEL(OF_buf)@ha
     86  1.2  matt 	stw	8,_C_LABEL(OF_buf)@l(9)
     87  1.1  matt 
     88  1.1  matt 	blr
     89  1.1  matt 
     90  1.1  matt /*
     91  1.1  matt  * OpenFirmware entry point
     92  1.1  matt  */
     93  1.1  matt 	.text
     94  1.1  matt ENTRY(openfirmware)
     95  1.1  matt 	mflr	0			/* save return address */
     96  1.1  matt 	stw	0,4(1)
     97  1.1  matt 	stwu	1,-16(1)		/* setup stack frame */
     98  1.1  matt 
     99  1.1  matt 	mfmsr	4			/* save msr */
    100  1.1  matt 	stw	4,8(1)
    101  1.1  matt 
    102  1.1  matt 	lis	4,openfirmware_entry@ha	/* get firmware entry point */
    103  1.1  matt 	lwz	4,openfirmware_entry@l(4)
    104  1.1  matt 	mtlr	4
    105  1.1  matt 
    106  1.1  matt 	li	0,0			/* clear battable translations */
    107  1.1  matt 	mtdbatu	2,0
    108  1.1  matt 	mtdbatu	3,0
    109  1.1  matt 	mtibatu	2,0
    110  1.1  matt 	mtibatu	3,0
    111  1.1  matt 
    112  1.1  matt 	lis	4,ofwsrsave@ha		/* save current SRs */
    113  1.1  matt 	addi	4,4,ofwsrsave@l
    114  1.1  matt 	li	5,0
    115  1.1  matt 1:	mfsrin	0,5
    116  1.1  matt 	stw	0,0(4)
    117  1.1  matt 	addi	4,4,4
    118  1.1  matt 	addis	5,5,0x10000000@h
    119  1.1  matt 	cmpwi	5,0
    120  1.1  matt 	bne	1b
    121  1.1  matt 
    122  1.1  matt 	mfsprg	5,0			/* save current sprg0 (curcpu) */
    123  1.1  matt 	lis	4,ofwsprg0save@ha
    124  1.1  matt 	addi	4,4,ofwsprg0save@l
    125  1.1  matt 	stw	5,0(4)
    126  1.1  matt 
    127  1.1  matt 	lis	4,_C_LABEL(ofw_pmap)@ha	/* load OFW SR */
    128  1.1  matt 	addi	4,4,_C_LABEL(ofw_pmap)@l
    129  1.1  matt 	lwz	0,PM_KERNELSR(4)
    130  1.1  matt 	cmpwi	0,0			/* pm_sr[KERNEL_SR] == 0? */
    131  1.1  matt 	beq	2f			/* then skip (not initialized yet) */
    132  1.1  matt 	li	5,0
    133  1.1  matt 1:	lwz	0,0(4)
    134  1.1  matt 	mtsrin	0,5
    135  1.1  matt 	addi	4,4,4
    136  1.1  matt 	addis	5,5,0x10000000@h
    137  1.1  matt 	cmpwi	5,0
    138  1.1  matt 	bne	1b
    139  1.1  matt 2:
    140  1.1  matt 	lis	4,ofmsr@ha		/* Open Firmware msr + sprg[0-3] */
    141  1.1  matt 	lwzu	5,ofmsr+16@l(4)
    142  1.1  matt 	mtsprg	3,5
    143  1.1  matt 	lwzu	5,-4(4)
    144  1.1  matt 	mtsprg	2,5
    145  1.1  matt 	lwzu	5,-4(4)
    146  1.1  matt 	mtsprg	1,5
    147  1.1  matt 	lwzu	5,-4(4)
    148  1.1  matt 	mtsprg	0,5
    149  1.1  matt 	lwz	5,-4(4)
    150  1.1  matt 	mtmsr	5
    151  1.1  matt 	isync
    152  1.1  matt 
    153  1.1  matt 	blrl				/* call Open Firmware */
    154  1.1  matt 
    155  1.1  matt 	lis	4,ofwsprg0save@ha	/* restore saved sprg0 (curcpu) */
    156  1.1  matt 	addi	4,4,ofwsprg0save@l
    157  1.1  matt 	lwz	5,0(4)
    158  1.1  matt 	mtsprg	0,5
    159  1.1  matt 
    160  1.1  matt 	lis	4,ofwsrsave@ha		/* restore saved SRs */
    161  1.1  matt 	addi	4,4,ofwsrsave@l
    162  1.1  matt 	li	5,0
    163  1.1  matt 1:	lwz	0,0(4)
    164  1.1  matt 	mtsrin	0,5
    165  1.1  matt 	addi	4,4,4
    166  1.1  matt 	addis	5,5,0x10000000@h
    167  1.1  matt 	cmpwi	5,0
    168  1.1  matt 	bne	1b
    169  1.1  matt 
    170  1.1  matt 	lwz	4,8(1)			/* restore msr */
    171  1.1  matt 	mtmsr	4
    172  1.1  matt 	isync
    173  1.1  matt 
    174  1.1  matt 	lwz	1,0(1)			/* and return */
    175  1.1  matt 	lwz	0,4(1)
    176  1.1  matt 	mtlr	0
    177  1.1  matt 	blr
    178  1.1  matt 
    179  1.1  matt /*
    180  1.1  matt  * Switch to/from OpenFirmware real mode stack
    181  1.1  matt  *
    182  1.1  matt  * Note: has to be called as the very first thing in OpenFirmware interface
    183  1.1  matt  * routines.
    184  1.1  matt  * E.g.:
    185  1.1  matt  * int
    186  1.1  matt  * OF_xxx(arg1, arg2)
    187  1.1  matt  * type arg1, arg2;
    188  1.1  matt  * {
    189  1.1  matt  *	static struct {
    190  1.1  matt  *		char *name;
    191  1.1  matt  *		int nargs;
    192  1.1  matt  *		int nreturns;
    193  1.1  matt  *		char *method;
    194  1.1  matt  *		int arg1;
    195  1.1  matt  *		int arg2;
    196  1.1  matt  *		int ret;
    197  1.1  matt  *	} args = {
    198  1.1  matt  *		"xxx",
    199  1.1  matt  *		2,
    200  1.1  matt  *		1,
    201  1.1  matt  *	};
    202  1.1  matt  *
    203  1.1  matt  *	ofw_stack();
    204  1.1  matt  *	args.arg1 = arg1;
    205  1.1  matt  *	args.arg2 = arg2;
    206  1.1  matt  *	if (openfirmware(&args) < 0)
    207  1.1  matt  *		return -1;
    208  1.1  matt  *	return args.ret;
    209  1.1  matt  * }
    210  1.1  matt  */
    211  1.1  matt 
    212  1.1  matt ENTRY(ofw_stack)
    213  1.1  matt 	mfmsr	8			/* turn off interrupts */
    214  1.1  matt 	andi.	0,8,~(PSL_EE|PSL_RI)@l
    215  1.1  matt 	mtmsr	0
    216  1.1  matt 	stw	8,4(1)			/* abuse return address slot */
    217  1.1  matt 
    218  1.1  matt 	lwz	5,0(1)			/* get length of stack frame */
    219  1.1  matt 	subf	5,1,5
    220  1.1  matt 
    221  1.1  matt 	lis	7,firmstk+NBPG-8@ha
    222  1.1  matt 	addi	7,7,firmstk+NBPG-8@l
    223  1.1  matt 	lis	6,ofw_back@ha
    224  1.1  matt 	addi	6,6,ofw_back@l
    225  1.1  matt 	subf	4,5,7			/* make room for stack frame on
    226  1.1  matt 					   new stack */
    227  1.1  matt 	stw	6,-4(7)			/* setup return pointer */
    228  1.1  matt 	stwu	1,-8(7)
    229  1.1  matt 
    230  1.1  matt 	stw	7,-8(4)
    231  1.1  matt 
    232  1.1  matt 	addi	3,1,8
    233  1.1  matt 	addi	1,4,-8
    234  1.1  matt 	subi	5,5,8
    235  1.1  matt 
    236  1.1  matt 	b	_C_LABEL(ofbcopy)	/* and copy it */
    237  1.1  matt 
    238  1.1  matt ofw_back:
    239  1.1  matt 	lwz	1,0(1)			/* get callers original stack pointer */
    240  1.1  matt 
    241  1.1  matt 	lwz	0,4(1)			/* get saved msr from abused slot */
    242  1.1  matt 	mtmsr	0
    243  1.1  matt 
    244  1.1  matt 	lwz	1,0(1)			/* return */
    245  1.1  matt 	lwz	0,4(1)
    246  1.1  matt 	mtlr	0
    247  1.1  matt 	blr
    248