Home | History | Annotate | Line # | Download | only in oea
ofw_subr.S revision 1.6
      1  1.6  garbled /*	$NetBSD: ofw_subr.S,v 1.6 2008/01/28 21:06:29 garbled 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.4  aymeric GLOBAL(ofwreal_incharge)
     48  1.4  aymeric 	.long	0
     49  1.4  aymeric 
     50  1.1     matt 	.comm	firmstk,NBPG,8
     51  1.1     matt 	.comm	OF_buffer,NBPG,4
     52  1.1     matt 	.comm	openfirmware_entry,4,4	/* openfirmware entry point */
     53  1.1     matt 	.comm	ofwsrsave,64,4		/* openfirmware SR savearea */
     54  1.1     matt 
     55  1.1     matt /*
     56  1.1     matt  * Called by start to save the initial OFW state so we can restore it
     57  1.1     matt  * when call back to OFW.
     58  1.1     matt  */
     59  1.1     matt ENTRY_NOPROFILE(ofwinit)
     60  1.1     matt #ifdef	FIRMWORKSBUGS
     61  1.1     matt 	mfmsr	0
     62  1.1     matt 	andi.	0,0,PSL_IR|PSL_DR
     63  1.1     matt 	beq	1f
     64  1.1     matt 
     65  1.4  aymeric 	li	8,1
     66  1.4  aymeric 	lis	9,ofwreal_incharge@ha
     67  1.4  aymeric 	stw	8,ofwreal_incharge@l(9)
     68  1.4  aymeric 
     69  1.1     matt 	mflr	30
     70  1.1     matt 	bl	_C_LABEL(ofwr_init)
     71  1.1     matt 	mtlr	30
     72  1.1     matt 1:
     73  1.1     matt #endif
     74  1.1     matt 	lis	8,openfirmware_entry@ha
     75  1.1     matt 	stw	5,openfirmware_entry@l(8) /* save client interface handler*/
     76  1.1     matt 
     77  1.1     matt 	mfmsr	0
     78  1.1     matt 	lis	9,ofmsr@ha
     79  1.1     matt 	stwu	0,ofmsr@l(9)		/* save initial MSR value */
     80  1.1     matt 
     81  1.1     matt         mfsprg  0,0			/* save SPRGs */
     82  1.1     matt        	stwu	0,4(9)
     83  1.1     matt         mfsprg  0,1
     84  1.1     matt        	stwu	0,4(9)
     85  1.1     matt         mfsprg  0,2
     86  1.1     matt        	stwu	0,4(9)
     87  1.1     matt         mfsprg  0,3
     88  1.1     matt        	stw	0,4(9)
     89  1.1     matt 
     90  1.2     matt 	lis	8,OF_buffer@ha
     91  1.2     matt 	addi	8,8,OF_buffer@l
     92  1.1     matt 	lis	9,_C_LABEL(OF_buf)@ha
     93  1.2     matt 	stw	8,_C_LABEL(OF_buf)@l(9)
     94  1.1     matt 
     95  1.1     matt 	blr
     96  1.1     matt 
     97  1.1     matt /*
     98  1.1     matt  * OpenFirmware entry point
     99  1.1     matt  */
    100  1.1     matt 	.text
    101  1.1     matt ENTRY(openfirmware)
    102  1.1     matt 	mflr	0			/* save return address */
    103  1.1     matt 	stw	0,4(1)
    104  1.1     matt 	stwu	1,-16(1)		/* setup stack frame */
    105  1.1     matt 
    106  1.1     matt 	lis	4,openfirmware_entry@ha	/* get firmware entry point */
    107  1.1     matt 	lwz	4,openfirmware_entry@l(4)
    108  1.1     matt 	mtlr	4
    109  1.1     matt 
    110  1.4  aymeric 	mfsprg	5,0			/* save current sprg0 (curcpu) */
    111  1.4  aymeric 	lis	4,ofwsprg0save@ha
    112  1.4  aymeric 	addi	4,4,ofwsprg0save@l
    113  1.4  aymeric 	stw	5,0(4)
    114  1.4  aymeric 
    115  1.4  aymeric #ifdef FIRMWORKSBUGS
    116  1.4  aymeric 	lis	4,ofwreal_incharge@ha
    117  1.4  aymeric 	lwz	4,ofwreal_incharge@l(4)
    118  1.4  aymeric 	cmpwi	4,1
    119  1.4  aymeric 	bne	1f
    120  1.4  aymeric 	blrl
    121  1.6  garbled 	b	4f
    122  1.4  aymeric 1:
    123  1.6  garbled #endif
    124  1.4  aymeric 	mfmsr	4			/* save msr */
    125  1.4  aymeric 	stw	4,8(1)
    126  1.4  aymeric 
    127  1.1     matt 	li	0,0			/* clear battable translations */
    128  1.6  garbled #if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
    129  1.1     matt 	mtdbatu	2,0
    130  1.1     matt 	mtdbatu	3,0
    131  1.1     matt 	mtibatu	2,0
    132  1.1     matt 	mtibatu	3,0
    133  1.3  sanjayl #endif /* PPC_OEA */
    134  1.1     matt 
    135  1.1     matt 	lis	4,ofwsrsave@ha		/* save current SRs */
    136  1.1     matt 	addi	4,4,ofwsrsave@l
    137  1.1     matt 	li	5,0
    138  1.1     matt 1:	mfsrin	0,5
    139  1.1     matt 	stw	0,0(4)
    140  1.1     matt 	addi	4,4,4
    141  1.1     matt 	addis	5,5,0x10000000@h
    142  1.1     matt 	cmpwi	5,0
    143  1.1     matt 	bne	1b
    144  1.1     matt 
    145  1.1     matt 	lis	4,_C_LABEL(ofw_pmap)@ha	/* load OFW SR */
    146  1.1     matt 	addi	4,4,_C_LABEL(ofw_pmap)@l
    147  1.1     matt 	lwz	0,PM_KERNELSR(4)
    148  1.1     matt 	cmpwi	0,0			/* pm_sr[KERNEL_SR] == 0? */
    149  1.1     matt 	beq	2f			/* then skip (not initialized yet) */
    150  1.1     matt 	li	5,0
    151  1.1     matt 1:	lwz	0,0(4)
    152  1.1     matt 	mtsrin	0,5
    153  1.1     matt 	addi	4,4,4
    154  1.1     matt 	addis	5,5,0x10000000@h
    155  1.1     matt 	cmpwi	5,0
    156  1.1     matt 	bne	1b
    157  1.1     matt 2:
    158  1.1     matt 	lis	4,ofmsr@ha		/* Open Firmware msr + sprg[0-3] */
    159  1.1     matt 	lwzu	5,ofmsr+16@l(4)
    160  1.1     matt 	mtsprg	3,5
    161  1.1     matt 	lwzu	5,-4(4)
    162  1.1     matt 	mtsprg	2,5
    163  1.1     matt 	lwzu	5,-4(4)
    164  1.1     matt 	mtsprg	1,5
    165  1.1     matt 	lwzu	5,-4(4)
    166  1.1     matt 	mtsprg	0,5
    167  1.1     matt 	lwz	5,-4(4)
    168  1.1     matt 	mtmsr	5
    169  1.1     matt 	isync
    170  1.1     matt 
    171  1.1     matt 	blrl				/* call Open Firmware */
    172  1.1     matt 
    173  1.1     matt 	lis	4,ofwsrsave@ha		/* restore saved SRs */
    174  1.1     matt 	addi	4,4,ofwsrsave@l
    175  1.1     matt 	li	5,0
    176  1.1     matt 1:	lwz	0,0(4)
    177  1.1     matt 	mtsrin	0,5
    178  1.1     matt 	addi	4,4,4
    179  1.1     matt 	addis	5,5,0x10000000@h
    180  1.1     matt 	cmpwi	5,0
    181  1.1     matt 	bne	1b
    182  1.1     matt 
    183  1.1     matt 	lwz	4,8(1)			/* restore msr */
    184  1.1     matt 	mtmsr	4
    185  1.1     matt 	isync
    186  1.6  garbled 4:
    187  1.4  aymeric 	lis	4,ofwsprg0save@ha	/* restore saved sprg0 (curcpu) */
    188  1.4  aymeric 	addi	4,4,ofwsprg0save@l
    189  1.4  aymeric 	lwz	5,0(4)
    190  1.4  aymeric 	mtsprg	0,5
    191  1.1     matt 
    192  1.1     matt 	lwz	1,0(1)			/* and return */
    193  1.1     matt 	lwz	0,4(1)
    194  1.1     matt 	mtlr	0
    195  1.1     matt 	blr
    196  1.1     matt 
    197  1.1     matt /*
    198  1.1     matt  * Switch to/from OpenFirmware real mode stack
    199  1.1     matt  *
    200  1.1     matt  * Note: has to be called as the very first thing in OpenFirmware interface
    201  1.1     matt  * routines.
    202  1.1     matt  * E.g.:
    203  1.1     matt  * int
    204  1.1     matt  * OF_xxx(arg1, arg2)
    205  1.1     matt  * type arg1, arg2;
    206  1.1     matt  * {
    207  1.1     matt  *	static struct {
    208  1.1     matt  *		char *name;
    209  1.1     matt  *		int nargs;
    210  1.1     matt  *		int nreturns;
    211  1.1     matt  *		char *method;
    212  1.1     matt  *		int arg1;
    213  1.1     matt  *		int arg2;
    214  1.1     matt  *		int ret;
    215  1.1     matt  *	} args = {
    216  1.1     matt  *		"xxx",
    217  1.1     matt  *		2,
    218  1.1     matt  *		1,
    219  1.1     matt  *	};
    220  1.1     matt  *
    221  1.1     matt  *	ofw_stack();
    222  1.1     matt  *	args.arg1 = arg1;
    223  1.1     matt  *	args.arg2 = arg2;
    224  1.1     matt  *	if (openfirmware(&args) < 0)
    225  1.1     matt  *		return -1;
    226  1.1     matt  *	return args.ret;
    227  1.1     matt  * }
    228  1.1     matt  */
    229  1.1     matt 
    230  1.1     matt ENTRY(ofw_stack)
    231  1.1     matt 	mfmsr	8			/* turn off interrupts */
    232  1.1     matt 	andi.	0,8,~(PSL_EE|PSL_RI)@l
    233  1.1     matt 	mtmsr	0
    234  1.1     matt 	stw	8,4(1)			/* abuse return address slot */
    235  1.1     matt 
    236  1.1     matt 	lwz	5,0(1)			/* get length of stack frame */
    237  1.1     matt 	subf	5,1,5
    238  1.1     matt 
    239  1.1     matt 	lis	7,firmstk+NBPG-8@ha
    240  1.1     matt 	addi	7,7,firmstk+NBPG-8@l
    241  1.1     matt 	lis	6,ofw_back@ha
    242  1.1     matt 	addi	6,6,ofw_back@l
    243  1.1     matt 	subf	4,5,7			/* make room for stack frame on
    244  1.1     matt 					   new stack */
    245  1.1     matt 	stw	6,-4(7)			/* setup return pointer */
    246  1.1     matt 	stwu	1,-8(7)
    247  1.1     matt 
    248  1.1     matt 	stw	7,-8(4)
    249  1.1     matt 
    250  1.1     matt 	addi	3,1,8
    251  1.1     matt 	addi	1,4,-8
    252  1.1     matt 	subi	5,5,8
    253  1.1     matt 
    254  1.1     matt 	b	_C_LABEL(ofbcopy)	/* and copy it */
    255  1.1     matt 
    256  1.1     matt ofw_back:
    257  1.1     matt 	lwz	1,0(1)			/* get callers original stack pointer */
    258  1.1     matt 
    259  1.1     matt 	lwz	0,4(1)			/* get saved msr from abused slot */
    260  1.1     matt 	mtmsr	0
    261  1.1     matt 
    262  1.1     matt 	lwz	1,0(1)			/* return */
    263  1.1     matt 	lwz	0,4(1)
    264  1.1     matt 	mtlr	0
    265  1.1     matt 	blr
    266