Page 1 of 1
Intel HD Audio - DMA buffers not working
Posted: Sun Oct 11, 2015 4:23 pm
by hgoel
I'm working on a driver for HD audio controllers, but I can't seem to get the CORB and RIRB buffers to work. It seems like the CORB DMA engine is instantly turning off after turning on without doing anything, I have no idea why it isn't working.
My code is here:
https://github.com/himanshugoel2797/Ape ... hda/ihda.c
The commands I'm using to test are:
Code: Select all
IHDA_Initialize();
IHDA_WriteVerb(0xF00 | 4);
COM_WriteStr("COMD!!!!!\r\n\r\n");
IHDA_WriteVerb(0xF00 | 4);
COM_WriteStr("Recieving\r\n");
uint64_t a = IHDA_ReadResponse();
COM_WriteStr("Reply: %x%x\r\n", (uint32_t)(a >> 32), (uint32_t)(a));
It gets through to the second WriteVerb where it infinite loops because the CORB RP indicates that the previous command hasn't been processed yet.
Re: Intel HD Audio - DMA buffers not working
Posted: Mon Oct 12, 2015 10:06 am
by hgoel
It seems I kind of managed to get the DMA engines to work and update the pointers, although I can't seem to get any real output.
It turns out that the RIRB read position value needs to be incremented after each command as if we're required to read immediately after sending the verb.
EDIT: Got everything working (once the DMA stuff was working, I was getting the proper response, I just wasn't parsing it correctly)
Re: Intel HD Audio - DMA buffers not working
Posted: Mon Oct 12, 2015 11:19 pm
by hgoel
Now I have another problem, everything seems to work OK in a VM but on real hardware the number of AFGs is always zero on both HD audio controllers on my system. Only one codec is detected on each. I'm thinking it might have something to do with interacting with the Intel HD graphics? The docs mention stuff about disabling and reenabling the audio controller. Anyone have experience dealing with this stuff? I'm testing on a Haswell with a PCH8 chipset (a Lenovo y40 laptop)
Re: Intel HD Audio - DMA buffers not working
Posted: Mon Oct 26, 2015 5:16 pm
by SpyderTL
Your post inspired me to start working on my HD Audio code. I've got the reset bit working properly, but my Get Parameter command always returns a value of 0x00 (32-bits), regardless of whether I use the Immediate Command Register, or the CORB / RIRB buffers.
I'm sending the verb 0x000F0000, to get the vendor id of the first codec. (VirtualBox only has one codec -- the status register that shows all of the connected codecs as bit flags returns 0x01)
Anyone have any idea what I'm missing here?
Edit: more info... I went through the VirtualBox source, and everything looks like it should be working, but I'm getting back all zeros no matter which command I send, or which property I request. I've set up the CORB and RIRB buffer addresses and sizes, and enabled both of them.
On the immediate command register side, I'm getting the bit set that says that the return value is valid, but it's always set to zero as well.
Edit 2: Okay, I found the data sitting in the RIRB, and it looks correct. I knew that the RIRB entries were 8 bytes long, each. But I thought that the data would be in the second dword, not the first.
So that only leaves the immediate registers not working. Anyone have any idea how to get them to work? I'll probably just ignore them, now that I've got the buffers working, but it would be nice to know what I'm doing wrong...
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 11:32 am
by DavidCooper
SpyderTL wrote:So that only leaves the immediate registers not working. Anyone have any idea how to get them to work? I'll probably just ignore them, now that I've got the buffers working, but it would be nice to know what I'm doing wrong...
Are you polling the status register to see when a response is ready to collect or are you making the mistake of trying to collect it straight away? It takes a long time for the command to be sent across the link and for the response to come back, so you have to wait. I only used the immediate command registers when doing initial experiments where I just stuck a long delay loop in between sending a command and collecting a response - I never bothered to look at the status register at all, but the proper way to do it is to poll the status register until it returns 1 for the appropriate bit, and then you should read the response and reset the bit in the status register it to zero so that it's ready for the next time.
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 11:38 am
by DavidCooper
hgoel0974 wrote:Now I have another problem, everything seems to work OK in a VM but on real hardware the number of AFGs is always zero on both HD audio controllers on my system. Only one codec is detected on each. I'm thinking it might have something to do with interacting with the Intel HD graphics? The docs mention stuff about disabling and reenabling the audio controller. Anyone have experience dealing with this stuff? I'm testing on a Haswell with a PCH8 chipset (a Lenovo y40 laptop)
There shouldn't be any conflict with any graphics controller. Perhaps you should post a list all the PCI devices on your machine along with the vendor ID and device ID for each to give us an idea of what you're up against.
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 12:41 pm
by SpyderTL
DavidCooper wrote:Are you polling the status register to see when a response is ready to collect or are you making the mistake of trying to collect it straight away?
Yes, I'm resetting the Response Valid bit (by writing a 0x02 to that register), writing the command verb to the command register, flipping the send command bit in the status register (0x01), and then waiting for the Response Valid bit to flip back on before reading the result register. (status AND 0x02 != 0x00)
Has anyone gotten this Immediate Command functionality working in (the latest version of) VirtualBox? I went through the source code online and as far as I can tell, it should be working.
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 1:10 pm
by SpyderTL
hgoel0974 wrote:Now I have another problem, everything seems to work OK in a VM but on real hardware the number of AFGs is always zero on both HD audio controllers on my system. Only one codec is detected on each. I'm thinking it might have something to do with interacting with the Intel HD graphics? The docs mention stuff about disabling and reenabling the audio controller. Anyone have experience dealing with this stuff? I'm testing on a Haswell with a PCH8 chipset (a Lenovo y40 laptop)
Try dumping all of the nodes, and looking at the hierarchy. Maybe the Audio Functions are further down the tree or something.
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 3:16 pm
by DavidCooper
Just in case it helps, here's what my code actually does:-
Load base address of HDA memory-mapped ports into ESI
Load command to send into EAX
Mov EAX to [ESI+60h] (to send command to command register)
Mov [ESI+68h] to AX (to read the status reg)
OR AL with 1 (to set bit 0)
Mov AX to [ESI+68h] (send result back to status reg - trigger the sending of the command)
Run a long delay loop (to ensure that the response has arrived)
Mov [ESI+64h] to EAX (read first four bytes of response)
Store value in EAX somewhere to examine it afterwards
Mov [ESI+64h] to EAX again (read next lot of four bytes and junk them - they'll all be zero)
Ret.
I can then poke different command verbs into the variable which I load EAX from at the top and call the routine again, never bothering to check bit-1 of the status register and never resetting it either. If I replaced the delay loop with code checking the status register and resetting bit-1 by writing a 1 to it (which should be done by reading the port, OR-ing it with 2, then posting the result back), it would be closer to what you're doing. Note that I also never check that the port is ready, but that's because I'm communicating with it slowly (manually changing the verb being sent each time) - there is no possibility of me running the routine again before the port is ready. It may be that my code won't work on all machines, but I only ever used it for initial explorations and then switched to using CORB and RIRB to do the thing properly. If hgoel hasn't yet written any code to use the immediate command register, it may be worth giving that a go just to check by another route whether the AFG groups really are missing from his codecs - it's all too easy for a bug to get into a more complex routine and leave you doubting the existence of things that are actually there.
Re: Intel HD Audio - DMA buffers not working
Posted: Thu Nov 05, 2015 6:25 pm
by SpyderTL
I didn't know you were supposed to read the output register twice. But it shouldn't matter if you throw the second dword away. I should still be getting something back in the first dword...