I'm trying to use OFW for the Pegasos2 emulation in QEMU that I'm working on but at the same time I'm trying to make this generic with the promise that it could later be used for other machines emulated by QEMU as well (such as 40p and Macs and maybe even sparc machines but for those compiling the OBP sources may be better as these two seem to have diverged too much, so this is only for PPC now and mainly focusing on Pegasos2 at first). Starting from Artyom's prep/qemu port I've got something starting but it's not working yet and I have several questions and need some advice on how to continue.
My current work in progress code is here:
that can be tested with the currently off-tree pegasos2 emulation from:
(this is QEMU with WIP pegasos2 patch) only needed to compile with configure --target-list=ppc-softmmu to get qemu-system-ppc with pegasos2 machine, then it can be tested with:
qemu-system-ppc -M pegasos2 -m 512 -bios qofwppc.rom -serial stdio
where qofwppc.rom is what's built from the above OFW fork. More info on the Pegasos2 emulation can be found here:
To keep it generic and easy to adapt in the future to other machines I'm trying to do what SLOF does and use a flattened DTB to pass initial parameters from QEMU to OFW and start from there instead of detecting hardware as it would be done on a real machine. (Since this is only for QEMU emulated machines, a lot of low level hardware init and testing that OFW would normally do on real hadrware can be skipped as those are not needed for a virtual machine.) I've attempted to port SLOF's fdt parsing, which is in fdt.fth. It's able to create the initial device tree but may have some problems so it needs to be reviewed by someone who knows OFW.
The rest is mostly a cut down version of cpu/ppc/prep/qemu with as much machine specific parts removed as I could. The idea I've tried was to put machine specifics in a drop-in (so a generic rom could be built for similar machines that would load the appropriate driver based on the device tree it got from QEMU or it would be easy to build different roms for different machines with common parts still being the same). I only have one such driver now: the pegasos2.bth implements that drop-in but some code I could not put in there as those do not seem to work in fc file so those are now in pegasos2.fth. Ideally these should also be in the machine specific driver but I'm not sure that's possible. If not then maybe the above idea can't work and we'll need separate rom image for each machine but maybe there are some Forth tricks I'm not aware of to make this work.
Currently this gets to an OFW prompt but detecting pci devices does not work yet. With the default (for pegasos2) cirrus vga a /pci/vga device node is created but I think it stops during that and does not detect any more pci devices. With -vga std (that's the normal QEMU Bochs compatible VGA) it freezes during init-ing the card and with my experimental -vga none -device ati-vga (that's also upstream in QEMU now) an unnamed node is created so something is wrong with PCI probing at the moment. Could it be because not properly doing memory scrub&release? The the prep/qemu rom has some code for this and SLOF fdt code also has some parts to handle that but I did not understand how this should work so I've disabled these but it could be this causes problems with memory management later?
Once this can be made working and would get PCI devices detected next question is if it would be possible to emulate the board's original firmware that the OSes running on it expect. It's an OpenFirmware implementation (SmartFirmware) but properties may be slightly different so it may be necessary to change some properties to match that but I'm not sure what's the best way to do that.
Lastly once Pegasos2 works I may be interested in trying to make this work with the emulated Mac machines in QEMU as well but it seems drivers for that would be needed as those are not included in the OFW sources so it may be a bigger task so for now I focus on Pegasos2 but keeping it open for future enhancement.
I think I need more understanding on how OFW works and if the above is possible at all or how to debug it further so I hope someone here can provide some insight or answer my questions to get me over these hurdles. (I've already read http://wiki.laptop.org/go/Forth_Lessons which was a great introduction also discussing OFW implementation details but that still left me with a lot of pieces missing so I'd need some more help.)
Thank you, BALATON Zoltan