[RFC 0/1] ATI R300 emulated grpahics card V2

aaron.zakhrov@gmail.com posted 1 patch 4 years, 5 months ago
Test asan failed
Test checkpatch failed
Test FreeBSD passed
Test docker-mingw@fedora failed
Test docker-clang@ubuntu failed
Test docker-quick@centos7 failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20191128064350.20727-1-aaron.zakhrov@gmail.com
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
[RFC 0/1] ATI R300 emulated grpahics card V2
Posted by aaron.zakhrov@gmail.com 4 years, 5 months ago
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

Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by no-reply@patchew.org 4 years, 5 months ago
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
Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by no-reply@patchew.org 4 years, 5 months ago
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
Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by Gerd Hoffmann 4 years, 5 months ago
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


Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by BALATON Zoltan 4 years, 5 months ago
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

Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by BALATON Zoltan 4 years, 5 months ago
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

Re: [RFC 0/1] ATI R300 emulated grpahics card V2
Posted by BALATON Zoltan 4 years, 3 months ago
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