Finally we have a working CG3 framebuffer with QEMU on SPARC32!
This patchset, minus integration of Bob's cpeek patches, should be fairly close to the final implementation. It includes FCode source for a CG3 ROM which can be probed using a patched version of QEMU, and should be applied on top of my previous v2 display patchset.
As a teaser, I've created the following images from my testing:
http://www.ilande.co.uk/tmp/sol8-1.png http://www.ilande.co.uk/tmp/sol8-2.png http://www.ilande.co.uk/tmp/sol8-3.png http://www.ilande.co.uk/tmp/debian-woody.png
Some discussion points: what should be the fallback behaviour if we fail an FCode ROM probe for the display? At the moment I attempt to execute an internal copy of the FCode payload directly, so if people are running OpenBIOS on systems which don't emulate SBus then there should be no difference in behaviour.
The only minor issue at the moment is that OpenBIOS will crash if you try to drive the display at 1152x900 rather than 1024x768. This is simply because there isn't enough room in the 2M address space for the extra 200K or so required for the extra screen area. We could probably fix this by trimming out some of the extras such as grubfs (and possibly pre-aligning parts of the memory image) but any ideas gratefully received. If you have access to proprietary ROM images then those should work with the patched QEMU too - please test and let me know.
Finally I've pushed my modifed QEMU source with updated OpenBIOS images to github for testing. Simply pass -vga cg3 on the command line and you will be switched onto the new CG3 framebuffer.
https://github.com/mcayland/qemu/tree/cg3-preview
As always thanks to everyone else for helping to make this possible - enjoy!
Mark Cave-Ayland (2): cg3: add new FCode ROM for QEMU's Sun CG3 framebuffer sbus: add probe for display device
openbios-devel/arch/sparc32/build.xml | 1 + openbios-devel/drivers/build.xml | 1 + openbios-devel/drivers/cgthree.fs | 154 +++++++++++++++++++++++++++++++++ openbios-devel/drivers/sbus.c | 30 ++++++- openbios-devel/drivers/sbus.fs | 27 ++++-- 5 files changed, 202 insertions(+), 11 deletions(-) create mode 100644 openbios-devel/drivers/cgthree.fs
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/build.xml | 1 + openbios-devel/drivers/build.xml | 1 + openbios-devel/drivers/cgthree.fs | 154 +++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 openbios-devel/drivers/cgthree.fs
diff --git a/openbios-devel/arch/sparc32/build.xml b/openbios-devel/arch/sparc32/build.xml index 035c25c..81c3586 100644 --- a/openbios-devel/arch/sparc32/build.xml +++ b/openbios-devel/arch/sparc32/build.xml @@ -4,6 +4,7 @@ <object source="tree.fs" target="forth"/> <object source="init.fs" target="forth"/> <object source="QEMU,tcx.bin" target="fcode" condition="DRIVER_SBUS"/> + <object source="QEMU,cgthree.bin" target="fcode" condition="DRIVER_SBUS"/> </dictionary>
<library name="sparc32" type="static" target="target"> diff --git a/openbios-devel/drivers/build.xml b/openbios-devel/drivers/build.xml index bd91335..edec6b5 100644 --- a/openbios-devel/drivers/build.xml +++ b/openbios-devel/drivers/build.xml @@ -31,6 +31,7 @@ </dictionary>
<fcode source="tcx.fs" name="QEMU,tcx.bin" condition="DRIVER_SBUS" /> + <fcode source="cgthree.fs" name="QEMU,cgthree.bin" condition="DRIVER_SBUS" /> <fcode source="vga.fs" name="QEMU,VGA.bin" condition="DRIVER_VGA" />
</build> diff --git a/openbios-devel/drivers/cgthree.fs b/openbios-devel/drivers/cgthree.fs new file mode 100644 index 0000000..7bf837e --- /dev/null +++ b/openbios-devel/drivers/cgthree.fs @@ -0,0 +1,154 @@ +\ +\ Fcode payload for QEMU CG3 graphics card +\ +\ This is the Forth source for an Fcode payload to initialise +\ the QEMU CG3 graphics card. +\ +\ (C) Copyright 2013 Mark Cave-Ayland +\ + +fcode-version3 + +\ +\ Instead of using fixed values for the framebuffer address and the width +\ and height, grab the ones passed in by QEMU/generated by OpenBIOS +\ + +: (find-xt) \ ( str len -- xt | -1 ) + $find if + exit + else + -1 + then +; + +" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt +" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt +" depth-bits" (find-xt) cell+ value depth-bits-xt +" line-bytes" (find-xt) cell+ value line-bytes-xt +" debug-type" (find-xt) value debug-type-xt + +: openbios-video-width openbios-video-width-xt @ ; +: openbios-video-height openbios-video-height-xt @ ; +: depth-bits depth-bits-xt @ ; +: line-bytes line-bytes-xt @ ; +: debug-type debug-type-xt execute ; + +\ +\ Registers +\ + +h# 400000 constant cg3-off-dac +h# 20 constant /cg3-off-dac + +h# 800000 constant cg3-off-fb +h# c0000 constant /cg3-off-fb + +: >cg3-reg-spec ( offset size -- encoded-reg ) + >r 0 my-address d+ my-space encode-phys r> encode-int encode+ +; + +: cg3-reg + \ A real cg3 rom appears to just map the entire region with a + \ single entry + h# 0 h# 1000000 >cg3-reg-spec + " reg" property +; + +: do-map-in ( offset size -- virt ) + >r my-space r> " map-in" $call-parent +; + +: do-map-out ( virt size ) + " map-out" $call-parent +; + +\ +\ DAC +\ + +-1 value cg3-dac +-1 value fb-addr + +: dac! ( data reg# -- ) + cg3-dac + c! +; + +external + +: color! ( r g b c# -- ) + 0 dac! ( r g b ) + swap rot ( b g r ) + 4 dac! ( b g ) + 4 dac! ( b ) + 4 dac! ( ) +; + +headerless + +\ +\ Mapping +\ + +: dac-map + cg3-off-dac /cg3-off-dac do-map-in to cg3-dac +; + +: fb-map + cg3-off-fb h# c0000 do-map-in to fb-addr +; + +: map-regs + dac-map fb-map +; + +\ +\ Installation +\ + +" cgthree" device-name +" display" device-type +" SUNW,501-1415" model + +: qemu-cg3-driver-install ( -- ) + cg3-dac -1 = if + map-regs + fb-addr to frame-buffer-adr + default-font set-font + + frame-buffer-adr encode-int " address" property + + openbios-video-width openbios-video-height over char-width / over char-height / + fb8-install + then +; + +: qemu-cg3-driver-init + + cg3-reg + + openbios-video-height encode-int " height" property + openbios-video-width encode-int " width" property + line-bytes encode-int " linebytes" property + + h# 39 encode-int 0 encode-int encode+ " intr" property + + \ Monitor sense. Some searching suggests that this is + \ 5 for 1024x768 and 7 for 1152x900 + openbios-video-width h# 480 = if + h# 7 + else + h# 5 + then + encode-int " monitor-sense" property + + " SUNW" encode-string " manufacturer" property + " ISO8859-1" encode-string " character-set" property + h# c encode-int " cursorshift" property + + ['] qemu-cg3-driver-install is-install +; + +qemu-cg3-driver-init + +end0
If we are unable to find valid FCode at the probe address then we fallback to the internal TCX driver in order to preserve existing behaviour.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/sbus.c | 30 ++++++++++++++++++++++++++++-- openbios-devel/drivers/sbus.fs | 27 ++++++++++++++++++--------- 2 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c index 6ef6bda..128f3a8 100644 --- a/openbios-devel/drivers/sbus.c +++ b/openbios-devel/drivers/sbus.c @@ -141,8 +141,34 @@ uint16_t graphic_depth; static void ob_tcx_init(unsigned int slot, const char *path) { - push_str(path); - fword("find-device"); + phandle_t ph = 0; + int found = 0; + char buf[6]; + + while ((ph = dt_iterate_type(ph, "display"))) { + found = -1; + } + + if (!found) { + printk("No display device located during SBus probe - falling back to internal TCX driver\n"); + + /* Make the sbus node the current instance and active package for probing */ + feval("active-package my-self"); + push_str("/iommu/sbus"); + feval("2dup find-device open-dev to my-self"); + + fword("new-device"); + PUSH(0); + PUSH(0); + snprintf(buf, 6, "%d,0", slot); + push_str(buf); + fword("set-args"); + feval("['] tcx-driver-fcode 2 cells + 1 byte-load"); + fword("finish-device"); + + /* Restore */ + feval("to my-self active-package!"); + } }
static void diff --git a/openbios-devel/drivers/sbus.fs b/openbios-devel/drivers/sbus.fs index fa8c95c..22f3f72 100644 --- a/openbios-devel/drivers/sbus.fs +++ b/openbios-devel/drivers/sbus.fs @@ -64,15 +64,24 @@ \ -------------------------------------------------------------------------
: probe-self-sbus ( arg-adr arg-len reg-adr reg-len fcode-adr fcode-len -- ) - 2drop - new-device - set-args
- \ Note: this is currently hardcoded to TCX for testing as we don't have - \ cpeek (yet). Once cpeek is in place, adapting this to probe any slot - \ will be faily easy. - " tcx-driver-fcode" $find drop 2 cells + - 1 byte-load + ['] decode-unit-sbus catch if + 2drop 2drop 2drop 2drop + exit + then + + h# 10000 map-in-sbus + + dup c@ + dup h# f1 = swap h# fd = or if + new-device + >r set-args r> + dup 1 byte-load + finish-device + else + nip nip nip nip + ." Invalid FCode start byte" cr + then
- finish-device + h# 10000 map-out-sbus ;
On 11/08/13 12:06, Mark Cave-Ayland wrote:
This patchset, minus integration of Bob's cpeek patches, should be fairly close to the final implementation. It includes FCode source for a CG3 ROM which can be probed using a patched version of QEMU, and should be applied on top of my previous v2 display patchset.
I've just applied all outstanding patches, including updating this patchset to use the cpeek implementation supplied by Bob. Hence we can now say that OpenBIOS supports SBus probing :)
The SBus probe function has been altered so that if an FCode probe fails then we fall back to the in-built hardwired C implementation, so there should be no behaviour change against current QEMU git master.
Now all that remains for CG3 support is to get the QEMU patches (including FCode ROMs) rebased and submitted upstream as per my github repository.
ATB,
Mark.