Had another quick go at TV card drivers under the final update and they no longer work at all....
IExec->StartDMA() now returns NULL so it's not starting the DMA properly. I suspect this is because the address I'm trying to start the DMA at looks suspiciously virtual (it was allocated MEMF_PUBLIC | MEMF_HWALIGNED I think it was). It always worked before but I seem to recall AllocMem() is no longer guaranteed to return a physical address, even in MEMF_PUBLIC.
Just for the heck of it I tried IMMU->GetPhysicalAddress() on the address that was allocated but this call just calls the Grim Reaper.
Does anyone have an example of how to use DMA (or interrupts for that matter though I may be ok on that) under the final update? Are there any open source DMA-capable drivers?
I you are aware of the fact that Exec/StartDMA() does not return a pointer, but a number of the DMA block lists, which must be allocated for the process.
I just tried calling IExec->LockMem on the address, no difference. But that address looks rather virtual to me, which I imagine may be no good for DMAing....
And yes, I am aware of that fact. :) The code works fine under Update 4. It currently returns NULL though.
All I need is to tell the Amiga that this block of memory is to be DMA'ed to by the TV card.
sg2 wrote: I'd be glad to help ; I'd have thought that the exec autodocs for startdma/getdmalist/enddma are rather well written (no, i did not write them :)
Can you please paste here your code :
- which allocates the dma buffer
- which is between startdma and enddma
They were written well but I think a little out of date now. :)
I'm away from my code ATM but... The code which allocates the buffer is just a standard IExec->AllocMem( size, MEMF_PUBLIC | MEMF_HWALIGNED) I think. As for what happens between the StartDMA and the EndDMA I can't remember, pretty much the same as the autodoc! However as StartDMA is returning NULL it doesn't get that far anyway! It's the StartDMA itself which is broken....
Which bit exactly do you need? I can send you the bit where I call StartDMA() and the allocation... if you really want it I can send you the bit after StartDMA too but there doesn't seem much point as it's never called (StartDMA returning NULL of course)...
printf("Frame buffer is at 0x%p.\n", mFrameBufferPhysical );
The bit about the FrameBufferPhysical is where I was trying to get the physical address. I didn't need to do that before. Also of course I didn't need to worry about going into Supervisor state or anything before. Also the LockMem() wasn't there before, I just put that in to see what would happen after it was suggested above.
By the way there's no reason why you'd need memf_public, you should rather use the new allocvectags, and ask for contiguous memory, with proper alignment.
Also, while it may sound wise to lockmem, its not necessary until the pager is running.
Finally, you don't have to get the physical address of your buffer, startdma takes a virtual address, and getdmalist will return the physical mappings of your buffer.
Note, given that allocvec can return scattered pages, if your DMA hardware does not support scatter/gather, then you HAVE to use allocvectags and explicitly ask for a contiguous buffer.
That's the second time someone's mentioned a function called AllocVecTags (or AllocVecTagList)...
I'm using the SDK on the Hyperion FTP site, v51.22... I'm starting to suspect there's a newer version which I don't have but without which I can't do anything... am I correct?
ssolie wrote: @Spirantho The AllocVecTags() function and other changes will be made available in the updated SDK.
@sg2 Are you sure you can do DMA drivers without the updated SDK on the new kernel?
Looks like that's what it needs. Kind of annoying really... spend ages waiting for overlay code and now I've got it I can't compile even a normal version yet. Hope the SDK doesn't take too long!
@sg2 The AllocVec returns the number I put in the debug output at the top.
indeed, we have abandoned memf_public as a safe way to allocate contiguous / physical=virtual buffers, in favor of a more flexible api but this obviously requires the new sdk...
Are you sure you can do DMA drivers without the updated SDK on the new kernel?
For hardware which supports scatter/gather DMA: Yes.
For hardware which doesn't but needs contiguous physical memory for DMA you need AllocVecTags() now and need the new SDK, up to Update4 you could use a MEMF_PUBLIC buffer instead.
IIRC it must be MEMF_SHARED | MEMF_HWALIGNED but I could be wrong because I never had the honour to write a DMAable driver. For GetPhysicalAddress() and friends you need to switch to Supervisor() mode, first.
Plus he does not need getphysicaladdress, the prd's returned by getdmalist are all he needs to set his dma hardware. If his hardware does not support scatter/gather then he has to allocate his buffer using the contiguous tag of allocvectags.
If he wants to cache flush the buffer, he needs a 32 byte aligned buffer at both ends to avoid side effects of ppc cache flushes.