Subject: Re: PowerPC G5 port update and Open Firmware woes
To: Sanjay Lal <sanjayl@kymasys.com>
From: Yevgeny Binder <yevbee@comcast.net>
List: port-macppc
Date: 07/10/2006 02:56:12
On Jul 10, 2006, at 2:18 AM, Sanjay Lal wrote:

> the problem is that in PoweMacs OFW runs in what the standard  
> defines as "virtual mode", i.e. with the MMU turned on. The kernel  
> switches the MSR + segment registers to what OFW expects before  
> calling the client interface.   The series of mtsrin instructions  
> basically blows away OFW's MMU context (see below for details).  
> That is why, even though the MMU is disabled in the kernel context,  
> the system hangs once the OFW interface is called after the series  
> of mtsrin instructions.

But the ofwinit() routine in powerpc/oea/ofw_subr.S saves the initial  
OFW context that exists before the kernel starts to load, and the  
openfirmware() routine restores it prior to switching control to OFW.  
Unless the code is faulty, all of the segment registers should be  
loaded up to their correct virtual-mode values before the branch to  
<openfirmware_entry>, and then subsequently restored to whatever  
values the kernel had before, so that it shouldn't make any  
difference if the kernel calls mtsrin or not. What bothers me is that  
the code does seem to be buggy, but I can't figure out how.

> As it stands today the code is as follows:
>
> (1) Save OFW translations (machdep.c : save_ofmap())
> (2) pmap_bootstrap() (ofw_pmap is not initialized yet!!)
> (3) Restore the OFW translations that NetBSD needs by loading them  
> up in ofw_pmap (machdep.c: restore_ofmap).
>
> Unfortunately, restore_ofmap uses pmap_enter() which can only be  
> called once the pmap layer is up.

Let me make sure I understand: Currently, OFW is not expected to work  
until after restore_ofmap() is called, right?

> Currently, I insert page table entries for the OFW code+data in  
> pmap_setup_segment0_map(). I think things will fare better if you  
> add in PTEs (uncached) for the framebuffer  Also, you need to  
> modify restore_ofmap() so that the map entries for the framebuffer  
> are loaded into ofw_pmap.

The issues I'm having occur within pmap_bootstrap(), before  
restore_ofmap() is called. The goal is to be able to call printf() at  
any point in the kernel code and have it do whatever it needs to OFW  
to print out data. If we have to wait until restore_ofmap() is  
called, what's the point of having an early console? I think there  
has to be another way. What do you think about the callback  
mechanism? Is it something worthwhile to pursue?

Oh a thought I just had as I was reading over what I wrote: The PPC64  
PEM states that mtsrin instructions need to be followed, and possibly  
also preceded, by a context-synchronizing instruction. But these are  
absent in pmap_bootstrap(). Could this be a clue? I'll test it out  
tomorrow.

Thanks,
Yevgeny

> On Jul 8, 2006, at 11:46 PM, Yevgeny Binder wrote:
>
>> After this point, however, pmap_bootstrap() starts to load the 16  
>> segment registers with a loop of mtsrin instructions. Console  
>> output stops upon the first load. I don't understand what effect  
>> this should have: Address translation has not yet been enabled in  
>> the kernel when this happens, and the Open Firmware client  
>> interface routines load up their own segment registers anyway. My  
>> only guess was that the addresses that I pass to dcbf, which I got  
>> from Open Firmware (and are hence virtual addresses in OFW's  
>> context, supposedly), somehow become invalid after the mtsrin. But  
>> if address translation is off in the kernel the whole time  
>> through, how can that be?
>