@John Hoff

John, great work!

> Now what? I am not sure what to do with any of this data....

Now the hard part. Here's what I think is going on:

The windows driver running in the VM controls the audio codec. How?
According to section 4.4 of the Intel HDA Spec [1], the driver writes to
a circular buffer known as the Command Output Ring Buffer (CORB). The
HDA controller, which is implemented by the hardware manufacturer and
shipped as firmware in the chipset, takes commands from the CORB and
sends them to the codec.

Qemu provides the memory for the VM. That means qemu can see every time
the VM writes to memory. That's a lot of writes! We only care about the
subset of writes to the memory region allocated for the HDA controller,
which is what we get when we specify "vfio_region_write" event tracing.
My laptop has this HDA controller

00:1f.3 Multimedia audio controller [0401]: Intel Corporation Cannon
Point-LP High Definition Audio Controller [8086:9dc8] (rev 11)

so when I see qemu output a trace line that looks like

3064@1591386653.159507:vfio_region_write  (0000:00:1f.3:region0+0xe,
0x7fff, 2)

I know that the driver wrote to the HDA controller memory because the
pci device id "1f.3" matches the HDA controller. We can decode the rest
of the line by looking at the qemu source code [2]. 0xe is the memory
offset at which the driver wrote, 0x7fff is the data, and 2 is the size
of the data in bytes.

Which vfio_region_write events are CORB writes? The answer requires an
understanding of the CORB protocol. The CORB has a fixed size which may
be up to 256 entries. That means that all CORB writes are made to memory
within a CORBSIZE range of addresses. After the driver writes an HDA
verb to the CORB, the driver writes a value from 0x0 to 0xff to the CORB
Write Pointer (CORBWP) register which tells the HDA controller the last
valid CORB entry offset so the HDA controller knows how far to read
before stopping and waiting for more data.

Enter QemuHDADump (QHDAD). QHDAD is a program that someone wrote and
published on github which attempts to parse vfio_region_write lines from
qemu to determine the CORB address and record all HDA verbs written to
the CORB. The author of QHDAD has his/her own hardware and did not test
it on my laptop or your laptop so it is likely buggy and therefore may
not produce a good recording of verbs. We don't have to use QHDAD; we
just need some way to parse CORB writes from vfio_region_write events.

Because the speaker sound works on Windows that means that if we send
the verbs in the recording to the HDA controller using snd_hda_intel we
may be able to get the speakers work on Linux. Once we demonstrate that
the speakers function after passing all the verbs in the recording we
need to minimize the verbs if we want any hope of our patch being
included in the kernel. Many of the verbs will be "getters" instead of
"setters" which we can delete. After that it may be a tedious trial-and-
error process to see which of the remaining verbs we can delete. The
verb encodings are specified in the Intel HDA Spec which can help us
guess what can be deleted.

The end goal is a patch which looks like this one [3].

[1] 
https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf
[2] https://github.com/qemu/qemu/blob/master/hw/vfio/trace-events
[3] 
https://github.com/torvalds/linux/commit/a2ef03fe617a8365fb7794531b11ba587509a9b9

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1851518

Title:
  [950SBE/951SBE, Realtek ALC298, Speaker, Internal] No sound on
  internal speakers, very very quiet on headphones

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1851518/+subscriptions

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to