Home | History | Annotate | Line # | Download | only in oea
ofw_subr.S revision 1.3
      1  1.3  sanjayl /*	$NetBSD: ofw_subr.S,v 1.3 2006/08/05 21:26:49 sanjayl 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.3  sanjayl 	.globl	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.3  sanjayl #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
    108  1.1     matt 	mtdbatu	2,0
    109  1.1     matt 	mtdbatu	3,0
    110  1.1     matt 	mtibatu	2,0
    111  1.1     matt 	mtibatu	3,0
    112  1.3  sanjayl #endif /* PPC_OEA */
    113  1.1     matt 
    114  1.1     matt 	lis	4,ofwsrsave@ha		/* save current SRs */
    115  1.1     matt 	addi	4,4,ofwsrsave@l
    116  1.1     matt 	li	5,0
    117  1.1     matt 1:	mfsrin	0,5
    118  1.1     matt 	stw	0,0(4)
    119  1.1     matt 	addi	4,4,4
    120  1.1     matt 	addis	5,5,0x10000000@h
    121  1.1     matt 	cmpwi	5,0
    122  1.1     matt 	bne	1b
    123  1.1     matt 
    124  1.1     matt 	mfsprg	5,0			/* save current sprg0 (curcpu) */
    125  1.1     matt 	lis	4,ofwsprg0save@ha
    126  1.1     matt 	addi	4,4,ofwsprg0save@l
    127  1.1     matt 	stw	5,0(4)
    128  1.1     matt 
    129  1.1     matt 	lis	4,_C_LABEL(ofw_pmap)@ha	/* load OFW SR */
    130  1.1     matt 	addi	4,4,_C_LABEL(ofw_pmap)@l
    131  1.1     matt 	lwz	0,PM_KERNELSR(4)
    132  1.1     matt 	cmpwi	0,0			/* pm_sr[KERNEL_SR] == 0? */
    133  1.1     matt 	beq	2f			/* then skip (not initialized yet) */
    134  1.1     matt 	li	5,0
    135  1.1     matt 1:	lwz	0,0(4)
    136  1.1     matt 	mtsrin	0,5
    137  1.1     matt 	addi	4,4,4
    138  1.1     matt 	addis	5,5,0x10000000@h
    139  1.1     matt 	cmpwi	5,0
    140  1.1     matt 	bne	1b
    141  1.1     matt 2:
    142  1.1     matt 	lis	4,ofmsr@ha		/* Open Firmware msr + sprg[0-3] */
    143  1.1     matt 	lwzu	5,ofmsr+16@l(4)
    144  1.1     matt 	mtsprg	3,5
    145  1.1     matt 	lwzu	5,-4(4)
    146  1.1     matt 	mtsprg	2,5
    147  1.1     matt 	lwzu	5,-4(4)
    148  1.1     matt 	mtsprg	1,5
    149  1.1     matt 	lwzu	5,-4(4)
    150  1.1     matt 	mtsprg	0,5
    151  1.1     matt 	lwz	5,-4(4)
    152  1.1     matt 	mtmsr	5
    153  1.1     matt 	isync
    154  1.1     matt 
    155  1.1     matt 	blrl				/* call Open Firmware */
    156  1.1     matt 
    157  1.1     matt 	lis	4,ofwsprg0save@ha	/* restore saved sprg0 (curcpu) */
    158  1.1     matt 	addi	4,4,ofwsprg0save@l
    159  1.1     matt 	lwz	5,0(4)
    160  1.1     matt 	mtsprg	0,5
    161  1.1     matt 
    162  1.1     matt 	lis	4,ofwsrsave@ha		/* restore saved SRs */
    163  1.1     matt 	addi	4,4,ofwsrsave@l
    164  1.1     matt 	li	5,0
    165  1.1     matt 1:	lwz	0,0(4)
    166  1.1     matt 	mtsrin	0,5
    167  1.1     matt 	addi	4,4,4
    168  1.1     matt 	addis	5,5,0x10000000@h
    169  1.1     matt 	cmpwi	5,0
    170  1.1     matt 	bne	1b
    171  1.1     matt 
    172  1.1     matt 	lwz	4,8(1)			/* restore msr */
    173  1.1     matt 	mtmsr	4
    174  1.1     matt 	isync
    175  1.1     matt 
    176  1.1     matt 	lwz	1,0(1)			/* and return */
    177  1.1     matt 	lwz	0,4(1)
    178  1.1     matt 	mtlr	0
    179  1.1     matt 	blr
    180  1.1     matt 
    181  1.1     matt /*
    182  1.1     matt  * Switch to/from OpenFirmware real mode stack
    183  1.1     matt  *
    184  1.1     matt  * Note: has to be called as the very first thing in OpenFirmware interface
    185  1.1     matt  * routines.
    186  1.1     matt  * E.g.:
    187  1.1     matt  * int
    188  1.1     matt  * OF_xxx(arg1, arg2)
    189  1.1     matt  * type arg1, arg2;
    190  1.1     matt  * {
    191  1.1     matt  *	static struct {
    192  1.1     matt  *		char *name;
    193  1.1     matt  *		int nargs;
    194  1.1     matt  *		int nreturns;
    195  1.1     matt  *		char *method;
    196  1.1     matt  *		int arg1;
    197  1.1     matt  *		int arg2;
    198  1.1     matt  *		int ret;
    199  1.1     matt  *	} args = {
    200  1.1     matt  *		"xxx",
    201  1.1     matt  *		2,
    202  1.1     matt  *		1,
    203  1.1     matt  *	};
    204  1.1     matt  *
    205  1.1     matt  *	ofw_stack();
    206  1.1     matt  *	args.arg1 = arg1;
    207  1.1     matt  *	args.arg2 = arg2;
    208  1.1     matt  *	if (openfirmware(&args) < 0)
    209  1.1     matt  *		return -1;
    210  1.1     matt  *	return args.ret;
    211  1.1     matt  * }
    212  1.1     matt  */
    213  1.1     matt 
    214  1.1     matt ENTRY(ofw_stack)
    215  1.1     matt 	mfmsr	8			/* turn off interrupts */
    216  1.1     matt 	andi.	0,8,~(PSL_EE|PSL_RI)@l
    217  1.1     matt 	mtmsr	0
    218  1.1     matt 	stw	8,4(1)			/* abuse return address slot */
    219  1.1     matt 
    220  1.1     matt 	lwz	5,0(1)			/* get length of stack frame */
    221  1.1     matt 	subf	5,1,5
    222  1.1     matt 
    223  1.1     matt 	lis	7,firmstk+NBPG-8@ha
    224  1.1     matt 	addi	7,7,firmstk+NBPG-8@l
    225  1.1     matt 	lis	6,ofw_back@ha
    226  1.1     matt 	addi	6,6,ofw_back@l
    227  1.1     matt 	subf	4,5,7			/* make room for stack frame on
    228  1.1     matt 					   new stack */
    229  1.1     matt 	stw	6,-4(7)			/* setup return pointer */
    230  1.1     matt 	stwu	1,-8(7)
    231  1.1     matt 
    232  1.1     matt 	stw	7,-8(4)
    233  1.1     matt 
    234  1.1     matt 	addi	3,1,8
    235  1.1     matt 	addi	1,4,-8
    236  1.1     matt 	subi	5,5,8
    237  1.1     matt 
    238  1.1     matt 	b	_C_LABEL(ofbcopy)	/* and copy it */
    239  1.1     matt 
    240  1.1     matt ofw_back:
    241  1.1     matt 	lwz	1,0(1)			/* get callers original stack pointer */
    242  1.1     matt 
    243  1.1     matt 	lwz	0,4(1)			/* get saved msr from abused slot */
    244  1.1     matt 	mtmsr	0
    245  1.1     matt 
    246  1.1     matt 	lwz	1,0(1)			/* return */
    247  1.1     matt 	lwz	0,4(1)
    248  1.1     matt 	mtlr	0
    249  1.1     matt 	blr
    250