List Info

Thread: PowerPC G5 port update and Open Firmware woes




PowerPC G5 port update and Open Firmware woes
user name
2006-07-09 04:46:44
The past couple of weeks I've been using Sanjay Lal's
preliminary  
PowerPC 970 patches to run -current on my dual 2.0 G5
PowerMac. I can  
directly boot his modified INSTALL kernel without a
bootloader both  
over the network and from an internal hard disk. Console I/O
must be  
done over a serial line, and there is no native support for
the  
onboard SATA controller yet.

I've been trying to add display/keyboard console support,
with little  
success. The problem lies in the fact that 64-bit PowerPC
chips do  
not include the Block Address Translation (BAT) facility.
Open  
Firmware requires that the memory region mapped to the
display  
framebuffer be marked as cache-inhibited, so that updates
are written  
directly to video RAM. The BAT mechanism was used on earlier
PowerPC  
chips to accomplish this, by mapping the VRAM's physical
addresses to  
virtual memory and setting the I (cache inhibited) and G
(guarded)  
flags on the corresponding block table entries.

The only way to do this on the G5 is to use Segment Address 

Translation. This entails bringing up the entire pmap
interface. This  
is fine later in the boot process, but since we want to
_debug_ pmap  
and other machine-dependent initializations very early in
the kernel  
boot sequence, before address translation is enabled, we're
out of luck.

To try to tackle this issue, I first switched from the ofb
console  
device to ofcons, which is a more low-level interface with
less  
overhead. I find the address and size of the framebuffer
with Open  
Firmware's 'frame-buffer-adr' method and 'screen'
package properties,  
respectively. As a temporary measure, Allen Briggs suggested
that I  
manually flush the data cache of the entire framebuffer with
a loop  
of dcbf instructions. While this is grossly inefficient and
should  
eventually be replaced by a better solution, it does the
job, and  
I've gotten console output between the start of initppc()
and the  
uvm_page_physload() call within pmap_bootstrap().

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?

I took a copy of the openfirmware() assembly routine [1] and
modified  
it to call dcbf instead, so that the cache flush occurs in
the  
context of Open Firmware. This produces a very strange
result: After  
the first character appears on screen, the string
"Sttttttttttttttt"  
is displayed, and nothing else happens. (I've posted the
routine at  
[2] if anyone would like to check it over for correctness; I
would  
certainly appreciate it.)

It may seem overly optimistic to expect stuff to work while
pmap is  
still half-hatched, but I see no reason why this particular
operation  
in Open Firmware, which supposedly preserves and restores
the MMU  
state, shouldn't operate properly.

This adds to my existing suspicion that the OFW client
interface is  
not implemented correctly, or at least not on the G5.
Although it  
works well enough while the kernel's address translation is
off, it  
will still not work even after pmap is fully brought up. The
key, I  
believe, lies in the lack of an OFW callback routine. The
PowerPC OFW  
binding specs [3] state that when the client operating
system brings  
up its address translation mechanism and starts modifying
the MMU  
state, it must provide a callback routine in order to
continue using  
OFW services. It seems strange to me that the kernel has
been working  
correctly on older PPC machines without a callback
installed, but I  
believe that one is necessary in order to work on the G5.
Then again,  
I'm no expert, so I welcome your thoughts.

I would really appreciate any insights or advice that you
can give me  
on these issues.

Thank you,
Yevgeny Binder

References
[1] - see powerpc/oea/ofw_subr.S
[2] - http://netbsd-soc.sourceforge.net/projects/ppcg5/docs/

ofw_subr.S.20060708
        line 230 (ofw_flush_cache_range)
[3] - http://playground.sun.com/1275/bindings/ppc/rele
ase/ppc-2_1.html
PowerPC G5 port update and Open Firmware woes
user name
2006-07-10 07:18:31
Hi Yevgeny,

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.

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.  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.

Hope this helps
Sanjay

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?

PowerPC G5 port update and Open Firmware woes
user name
2006-07-10 18:30:53
FYI,

There is a new powerpc64 "port" (which is really
just gcc infrastructure
at this point) that Ross Harvey is working on.  You might
want to take a
look at this.  Possibly Ross can help out as a technical
resource as
well, since he seems to have at least some underlying
powerpc  64-bit
knowledge. 

-- 
Garrett D'Amore, Principal Software Engineer
Tadpole Computer / Computing Technologies Division,
General Dynamics C4 Systems
http://www.tadpolecom
puter.com/
Phone: 951 325-2134  Fax: 951 325-2191

[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )