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