hw/display/Kconfig | 9 +- hw/display/Makefile.objs | 2 + hw/display/r100d.h | 869 +++++++++ hw/display/r300.c | 1087 +++++++++++ hw/display/r300.h | 269 +++ hw/display/r300_2d.c | 190 ++ hw/display/r300_debug.c | 272 +++ hw/display/r300_reg.h | 1789 ++++++++++++++++++ hw/display/r300d.h | 343 ++++ hw/display/r500_reg.h | 801 ++++++++ hw/display/radeon_reg.h | 3725 ++++++++++++++++++++++++++++++++++++++ 11 files changed, 9355 insertions(+), 1 deletion(-) create mode 100644 hw/display/r100d.h create mode 100644 hw/display/r300.c create mode 100644 hw/display/r300.h create mode 100644 hw/display/r300_2d.c create mode 100644 hw/display/r300_debug.c create mode 100644 hw/display/r300_reg.h create mode 100644 hw/display/r300d.h create mode 100644 hw/display/r500_reg.h create mode 100644 hw/display/radeon_reg.h
From: Aaron Dominick <aaron.zakhrov@gmail.com> This is the cleaned up patchset to my previous RFC patch set. I could not reliably clean up my previous commits so I deleted my fork and started from scratch. The patch looks like a lot of changes but most of it is just register definitions copied from the kernel radeon DRM tree. What I have implemented so far seems to get a Linux guest to load the DRM and KMS drivers but it cannot find any CRTCs. dmesg also says that while the GART is allocated, it cannot bind any pages to it. Aaron Dominick (1): Cleaned up Work tree. The radeon_reg.h r300_reg.h and r500_reg.h files are from the kernel drm tree. They contain the register definitions for the R300 GPU hw/display/Kconfig | 9 +- hw/display/Makefile.objs | 2 + hw/display/r100d.h | 869 +++++++++ hw/display/r300.c | 1087 +++++++++++ hw/display/r300.h | 269 +++ hw/display/r300_2d.c | 190 ++ hw/display/r300_debug.c | 272 +++ hw/display/r300_reg.h | 1789 ++++++++++++++++++ hw/display/r300d.h | 343 ++++ hw/display/r500_reg.h | 801 ++++++++ hw/display/radeon_reg.h | 3725 ++++++++++++++++++++++++++++++++++++++ 11 files changed, 9355 insertions(+), 1 deletion(-) create mode 100644 hw/display/r100d.h create mode 100644 hw/display/r300.c create mode 100644 hw/display/r300.h create mode 100644 hw/display/r300_2d.c create mode 100644 hw/display/r300_debug.c create mode 100644 hw/display/r300_reg.h create mode 100644 hw/display/r300d.h create mode 100644 hw/display/r500_reg.h create mode 100644 hw/display/radeon_reg.h -- 2.24.0
Patchew URL: https://patchew.org/QEMU/20191128064350.20727-1-aaron.zakhrov@gmail.com/ Hi, This series failed the docker-quick@centos7 build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #!/bin/bash make docker-image-centos7 V=1 NETWORK=1 time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1 === TEST SCRIPT END === /tmp/qemu-test/src/hw/display/xlnx_dp.c:504: undefined reference to `aux_request' ../hw/display/dpcd.o: In function `dpcd_init': /tmp/qemu-test/src/hw/display/dpcd.c:141: undefined reference to `aux_init_mmio' collect2: error: ld returned 1 exit status make[1]: *** [qemu-system-aarch64] Error 1 make: *** [aarch64-softmmu/all] Error 2 Traceback (most recent call last): File "./tests/docker/docker.py", line 662, in <module> sys.exit(main()) --- raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=6382f7f5da9e408e8649412bf4aad739', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=1', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-c6g2zogs/src/docker-src.2019-11-28-12.30.21.7650:/var/tmp/qemu:z,ro', 'qemu:centos7', '/var/tmp/qemu/run', 'test-quick']' returned non-zero exit status 2. filter=--filter=label=com.qemu.instance.uuid=6382f7f5da9e408e8649412bf4aad739 make[1]: *** [docker-run] Error 1 make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-c6g2zogs/src' make: *** [docker-run-test-quick@centos7] Error 2 real 2m38.467s user 0m8.298s The full log is available at http://patchew.org/logs/20191128064350.20727-1-aaron.zakhrov@gmail.com/testing.docker-quick@centos7/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-devel@redhat.com
Patchew URL: https://patchew.org/QEMU/20191128064350.20727-1-aaron.zakhrov@gmail.com/ Hi, This series failed the docker-mingw@fedora build test. Please find the testing commands and their output below. If you have Docker installed, you can probably reproduce it locally. === TEST SCRIPT BEGIN === #! /bin/bash export ARCH=x86_64 make docker-image-fedora V=1 NETWORK=1 time make docker-test-mingw@fedora J=14 NETWORK=1 === TEST SCRIPT END === CC hw/i2c/aspeed_i2c.o CC hw/i2c/microbit_i2c.o /tmp/qemu-test/src/hw/display/r300.c: In function 'r300_mm_read': /tmp/qemu-test/src/hw/display/r300.c:161:36: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("RADEON_MEMSIZE %ld \n",val); ~~^ ~~~ %lld /tmp/qemu-test/src/hw/display/r300.c:414:53: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("RADEON_SCLK 0x%08lx \n",val); ~~~~^ ~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:449:51: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("GART REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,val); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:449:68: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("GART REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,val); ~~~~^ ~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:510:38: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("READING FROM 0x%08lx \n",addr); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:512:34: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,val); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:512:51: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,val); ~~~~^ ~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c: In function 'r300_mm_write': /tmp/qemu-test/src/hw/display/r300.c:849:28: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:849:45: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER 0x%08lx CONTAINS 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:852:34: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("R100 GART ADDR 0x%08lx GART PTR 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:852:51: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("R100 GART ADDR 0x%08lx GART PTR 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:858:38: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("WRITE MC_AGP ADDR 0x%08lx DATA 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:858:51: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("WRITE MC_AGP ADDR 0x%08lx DATA 0x%08lx \n",addr,data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:893:34: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("DAC/DISPLAY ADDR %lx DATA %lx \n",addr,data); ~~^ ~~~~ %llx /tmp/qemu-test/src/hw/display/r300.c:893:43: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("DAC/DISPLAY ADDR %lx DATA %lx \n",addr,data); ~~^ ~~~~ %llx /tmp/qemu-test/src/hw/display/r300.c:919:46: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER NOT IMPLEMENTED 0x%08lx \n",addr); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c:922:51: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'uint64_t' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("REGISTER NOT IMPLEMENTED DATA 0x%08lx \n",data); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c: In function 'r300_gart_write': /tmp/qemu-test/src/hw/display/r300.c:929:30: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("GART_WRITE 0x%08lx \n",addr); ~~~~^ ~~~~ %08llx /tmp/qemu-test/src/hw/display/r300.c: In function 'r300_gart_read': /tmp/qemu-test/src/hw/display/r300.c:932:29: error: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'hwaddr' {aka 'long long unsigned int'} [-Werror=format=] qemu_log("GART_READ 0x%08lx \n",addr); ~~~~^ ~~~~ %08llx cc1: all warnings being treated as errors make: *** [/tmp/qemu-test/src/rules.mak:69: hw/display/r300.o] Error 1 make: *** Waiting for unfinished jobs.... Traceback (most recent call last): File "./tests/docker/docker.py", line 662, in <module> --- raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['sudo', '-n', 'docker', 'run', '--label', 'com.qemu.instance.uuid=15c3f7c91a12420698980dd077ab89a5', '-u', '1001', '--security-opt', 'seccomp=unconfined', '--rm', '-e', 'TARGET_LIST=', '-e', 'EXTRA_CONFIGURE_OPTS=', '-e', 'V=', '-e', 'J=14', '-e', 'DEBUG=', '-e', 'SHOW_ENV=', '-e', 'CCACHE_DIR=/var/tmp/ccache', '-v', '/home/patchew/.cache/qemu-docker-ccache:/var/tmp/ccache:z', '-v', '/var/tmp/patchew-tester-tmp-1lh1ysyd/src/docker-src.2019-11-28-12.36.54.28264:/var/tmp/qemu:z,ro', 'qemu:fedora', '/var/tmp/qemu/run', 'test-mingw']' returned non-zero exit status 2. filter=--filter=label=com.qemu.instance.uuid=15c3f7c91a12420698980dd077ab89a5 make[1]: *** [docker-run] Error 1 make[1]: Leaving directory `/var/tmp/patchew-tester-tmp-1lh1ysyd/src' make: *** [docker-run-test-mingw@fedora] Error 2 real 2m41.065s user 0m8.253s The full log is available at http://patchew.org/logs/20191128064350.20727-1-aaron.zakhrov@gmail.com/testing.docker-mingw@fedora/?type=message. --- Email generated automatically by Patchew [https://patchew.org/]. Please send your feedback to patchew-devel@redhat.com
On Thu, Nov 28, 2019 at 12:13:49PM +0530, aaron.zakhrov@gmail.com wrote: > From: Aaron Dominick <aaron.zakhrov@gmail.com> > > This is the cleaned up patchset to my previous RFC patch set. > I could not reliably clean up my previous commits so I deleted my fork and started from scratch. > The patch looks like a lot of changes but most of it is just register definitions copied from the kernel radeon DRM tree. Adding headers should be a separate patch. Qemu has some infrastructure to sync files with the linux kernel tree (see scripts/update-linux-headers.sh). It's intended for uapi include files though, so it might not work for you. Also the register specs are not going to change, so future updates are unlikely, so doing a one-time manual copy wouldn't be too bad maintenance-wise. The code should probably be integrated with the existing ati-vga instead of just copying the code, i.e. it'll be "-device ati-vga,model=r300". As far I know crtc programming doesn't change much across models, so there should be a good chunk of shareable code. The infrastructure to branch into model-specific code is pretty rough right now, we might refine that, for example with some helper functions (ati_get_model() returning an enum, or ati_is_$model() functions returning bool, or both). Patches usually should pass scripts/checkpatch.pl codestyle checking. We can make exceptions when reasonable (headers copied from elsewhere for example). > What I have implemented so far seems to get a Linux guest to load the > DRM and KMS drivers but it cannot find any CRTCs. Might be the vgabios tables are lacking information, see https://git.seabios.org/cgit/seabios.git/tree/vgasrc/ati-tables.S Might be i2c emulation needs tweaks (so EDID fetch works). Trouble-shooting linux guests shouldn't be too hard, you have the source code so you can check what the driver tries to do and you can add debug printk's to trace where exactly things are failing ;) HTH, Gerd
On Thu, 28 Nov 2019, Gerd Hoffmann wrote: > The infrastructure to branch into model-specific code is pretty rough > right now, we might refine that, for example with some helper functions > (ati_get_model() returning an enum, or ati_is_$model() functions > returning bool, or both). Maybe we could define ATI_IS_$MODEL macros to save some typing but I thought it's not much better than the current if() and also model specific functions could be grouped into separate ati_$model files so we don't need too many branches in the main file. > Trouble-shooting linux guests shouldn't be too hard, you have the source > code so you can check what the driver tries to do and you can add debug > printk's to trace where exactly things are failing ;) I think the main difficulties are to find out how the card works then once one gets that the next question is how to implement that in QEMU: e.g. how can we make the micro engine emulation run in a separate thread. I think it probably can be done with existing qemu thread and locking functions. The synchronisation between CPU and GPU should be solved by the protocol between them (after all in real hardware they also run parallel so this should have been solved). If so, the micro engine thread may only have to read memory packets then generate register accesses. For this to work the register access FIFO may also need to be added which is now missing as in current version register writes are executed immediately but once we have both the CPU and micro engine that can access registers we either need to implement the FIFO or have some synchronisation between the two. This needs some thought. (If we have the register write FIFO then the actual drawing can also be done in a separate thread which is more like what the real GPU does but to make it simple I did not try that in first version.) If the microcode of the microengine/CCE could be reversed or is documented somewhere it may be easier to implement emulation of that instead of doing the packet parsing for all possible command packets of which there are quite a lot, but in the real GPU all those are handled by the small microcode. The ME/CCE is probably some VLIW processor with 40 bit instructions which likely have ops to read and write memory and access registers and maybe some branching and synchronisation but I have no idea how to find out which opcode means what. This microengine is probably very similar throughout the early Radeons, only the microcode changes so if we could implement that it might work for several cards (also even for Rage128Pro). Regards, BALATON Zoltan
On Fri, 29 Nov 2019, BALATON Zoltan wrote: > If the microcode of the microengine/CCE could be reversed or is documented > somewhere it may be easier to implement emulation of that instead of doing > the packet parsing for all possible command packets of which there are quite > a lot, but in the real GPU all those are handled by the small microcode. The > ME/CCE is probably some VLIW processor with 40 bit instructions which likely > have ops to read and write memory and access registers and maybe some > branching and synchronisation but I have no idea how to find out which opcode > means what. This microengine is probably very similar throughout the early > Radeons, only the microcode changes so if we could implement that it might > work for several cards (also even for Rage128Pro). This is the microcode that the driver uploads to the card that the ME should execute and presumably implements the PM4 way of programming the GPU via packets read from memory: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/radeon/R100_cp.bin This one is for R100 which is also used for RV100 I think; R300 has a different one but probably very similar: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/radeon/R300_cp.bin (and I've seen that even the MacOS driver for Rage128Pro uses a similar microcode but Linux does not implement DRM for that card so it's not in the kernel sources). Does this make sense to anyone? Later Radeons (after R600) have a different microengine with different microcode but some Adreno GPUs seem to be based on that. Those microcodes were reversed for the Linux Adreno driver and the freedreno project has some results but it does not match up with these older Radeons so I'm not sure if that's any use for understanding these microcodes. That's all I could find out so far, any help to get further is appreciated. Regards, BALATON Zoltan
On Sat, 30 Nov 2019, BALATON Zoltan wrote: > That's all I could find out so far, any help to get further is appreciated. I've created a ticket at my qmiga.osdn.io page where I've summarised previous discussion at one place which could be used to track what we know about it. See here: https://osdn.net/projects/qmiga/ticket/40018 Help getting further is still appreciated, I couldn't do much with this so far but if anyone knows anything about early Radeon microengine feel free to chime in. Regards, BALATON Zoltan
© 2016 - 2024 Red Hat, Inc.