Subject: Re: netbsd-current and ibook g4: kernel freeze
To: Michael Lorenz <macallan@netbsd.org>
From: leon zadorin <leonleon77@gmail.com>
List: port-macppc
Date: 02/01/2007 17:31:52
On 1/31/07, Michael Lorenz <macallan@netbsd.org> wrote:

> This early in kernel startup interrupts should be disabled and
> decrementer exceptions shouldn't occur. Having a look at the msr
> immediately before the exception fires might be helpful ( as in finding
> out where exactly it's enabled and why it only happens on a handful
> machines )

Ok,

I have been digging in the code a bit and I think the issue is mainly
concentrated in
ofw_subr.S in sys/arch/powerpc/oea

the routine in question is ENTRY(openfirmware) and the explicit call is:

        blrl /* call Open Firmware */

All up to this call seems not to generate any of the decrementer
exceptions and other errors, yet after this call it would appear that
errors begin to be generated...

But first I need someone to clear something up for me... AFAIK (albeit
my assembler knowledge is about 1.5 days old) the blrl will use the LR
register and such appears to be set in a few lines above (within the
same routine):

	lis	4,openfirmware_entry@ha	/* get firmware entry point */
	lwz	4,openfirmware_entry@l(4)
	mtlr	4

Which appears to take the address of openfirmware_entry variable...
But where is openfirmware_entry actually defined/assigned in macppc
port? It is declared in the same ofw_subr.S file as:

	.globl	openfirmware_entry

but that is it... should there be something else that is being
assigned to this global var?

The whole chunk of code follows

	.local	firmstk
	.globl	openfirmware_entry
	.local	ofwsrsave
	.local	OF_buffer

and then (whilst on the subject - if someone is willing to provide a
quick lesson/explanation of why there are multiple "1:" sections in
the following code - that would be extra cool)...

/*
 * OpenFirmware entry point
 */
	.text
ENTRY(openfirmware)
	mflr	0			/* save return address */
	stw	0,4(1)
	stwu	1,-16(1)		/* setup stack frame */

	mfmsr	4			/* save msr */
	stw	4,8(1)

	lis	4,openfirmware_entry@ha	/* get firmware entry point */
	lwz	4,openfirmware_entry@l(4)
	mtlr	4

	li	0,0			/* clear battable translations */
#if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
	mtdbatu	2,0
	mtdbatu	3,0
	mtibatu	2,0
	mtibatu	3,0
#endif /* PPC_OEA */

	lis	4,ofwsrsave@ha		/* save current SRs */
	addi	4,4,ofwsrsave@l
	li	5,0
1:	mfsrin	0,5
	stw	0,0(4)
	addi	4,4,4
	addis	5,5,0x10000000@h
	cmpwi	5,0
	bne	1b

	mfsprg	5,0			/* save current sprg0 (curcpu) */
	lis	4,ofwsprg0save@ha
	addi	4,4,ofwsprg0save@l
	stw	5,0(4)

	lis	4,_C_LABEL(ofw_pmap)@ha	/* load OFW SR */
	addi	4,4,_C_LABEL(ofw_pmap)@l
	lwz	0,PM_KERNELSR(4)
	cmpwi	0,0			/* pm_sr[KERNEL_SR] == 0? */
	beq	2f			/* then skip (not initialized yet) */
	li	5,0
1:	lwz	0,0(4)
	mtsrin	0,5
	addi	4,4,4
	addis	5,5,0x10000000@h
	cmpwi	5,0
	bne	1b
2:
	lis	4,ofmsr@ha		/* Open Firmware msr + sprg[0-3] */
	lwzu	5,ofmsr+16@l(4)
	mtsprg	3,5
	lwzu	5,-4(4)
	mtsprg	2,5
	lwzu	5,-4(4)
	mtsprg	1,5
	lwzu	5,-4(4)
	mtsprg	0,5
	lwz	5,-4(4)
	mtmsr	5
	isync

	blrl				/* call Open Firmware */

	lis	4,ofwsprg0save@ha	/* restore saved sprg0 (curcpu) */
	addi	4,4,ofwsprg0save@l
	lwz	5,0(4)
	mtsprg	0,5

	lis	4,ofwsrsave@ha		/* restore saved SRs */
	addi	4,4,ofwsrsave@l
	li	5,0
1:	lwz	0,0(4)
	mtsrin	0,5
	addi	4,4,4
	addis	5,5,0x10000000@h
	cmpwi	5,0
	bne	1b

	lwz	4,8(1)			/* restore msr */
	mtmsr	4
	isync

	lwz	1,0(1)			/* and return */
	lwz	0,4(1)
	mtlr	0
	blr