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