updated kerneldriver again for DMA cmdbuffer in mainmem: added MTRR-WC mapping now. Actually copying some stuff from Thomas :-), interesting read. I'll try to go without further cloning of that DMA area for now. (learning..)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12837 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -843,6 +843,7 @@ static status_t open_hook (const char* name, uint32 flags, void** cookie) {
|
|||||||
char shared_name[B_OS_NAME_LENGTH];
|
char shared_name[B_OS_NAME_LENGTH];
|
||||||
physical_entry map[1];
|
physical_entry map[1];
|
||||||
size_t net_buf_size;
|
size_t net_buf_size;
|
||||||
|
void *unaligned_dma_buffer;
|
||||||
|
|
||||||
/* find the device name in the list of devices */
|
/* find the device name in the list of devices */
|
||||||
/* we're never passed a name we didn't publish */
|
/* we're never passed a name we didn't publish */
|
||||||
@@ -881,28 +882,46 @@ static status_t open_hook (const char* name, uint32 flags, void** cookie) {
|
|||||||
/* we want to setup a 1Mb buffer (size must be multiple of B_PAGE_SIZE) */
|
/* we want to setup a 1Mb buffer (size must be multiple of B_PAGE_SIZE) */
|
||||||
net_buf_size = ((1 * 1024 * 1024) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
net_buf_size = ((1 * 1024 * 1024) + (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
||||||
/* create the area that will hold the DMA command buffer */
|
/* create the area that will hold the DMA command buffer */
|
||||||
si->dma_buffer_area =
|
si->unaligned_dma_area =
|
||||||
create_area("NV accelerant DMA cmd buffer",
|
create_area("NV DMA cmd buffer",
|
||||||
(void **)&(si->dma_buffer),
|
(void **)&unaligned_dma_buffer,
|
||||||
B_ANY_KERNEL_ADDRESS,
|
B_ANY_KERNEL_ADDRESS,
|
||||||
2 * net_buf_size, /* take twice the net size so we can have MTRR-WC even on old systems */
|
2 * net_buf_size, /* take twice the net size so we can have MTRR-WC even on old systems */
|
||||||
B_FULL_LOCK | B_CONTIGUOUS, /* both properties needed: GPU always needs access */
|
B_FULL_LOCK | B_CONTIGUOUS, /* both properties needed: GPU always needs access */
|
||||||
B_USER_CLONEABLE_AREA);
|
B_USER_CLONEABLE_AREA | B_READ_AREA | B_WRITE_AREA);
|
||||||
/* on error, abort */
|
/* on error, abort */
|
||||||
if (si->dma_buffer_area < 0)
|
if (si->unaligned_dma_area < 0)
|
||||||
{
|
{
|
||||||
/* free the already created shared_info area, and return the error */
|
/* free the already created shared_info area, and return the error */
|
||||||
result = si->dma_buffer_area;
|
result = si->unaligned_dma_area;
|
||||||
goto free_shared;
|
goto free_shared;
|
||||||
}
|
}
|
||||||
/* we also need the physical adress our DMA buffer resides in, as this needs to be
|
/* we (also) need the physical adress our DMA buffer is at, as this needs to be
|
||||||
* fed into the GPU's engine later on. So get the first page of our assigned buffer */
|
* fed into the GPU's engine later on. Get an aligned adress so we can use MTRR-WC
|
||||||
get_memory_map(si->dma_buffer, B_PAGE_SIZE, map, 1);
|
* even on older CPU's. */
|
||||||
si->dma_buffer_pci = (void*)((uint32)(map[0].address));
|
get_memory_map(unaligned_dma_buffer, B_PAGE_SIZE, map, 1);
|
||||||
/* set our net buffer at an aligned adress for MTRR-WC mapping even by older CPU's */
|
si->dma_buffer_pci = (void*)
|
||||||
/* (using MTRR-WC mapping will speed-up placing commands..) */
|
((((uint32)(map[0].address)) + net_buf_size - 1) & ~(net_buf_size - 1));
|
||||||
si->engine.dma.cmdbuffer = (uint32*)
|
|
||||||
((((uint32)(si->dma_buffer_pci)) + net_buf_size - 1) & ~(net_buf_size - 1));
|
/* map the net DMA command buffer into vmem, using Write Combining */
|
||||||
|
si->dma_area = map_physical_memory(
|
||||||
|
"NV aligned DMA cmd buffer", si->dma_buffer_pci, net_buf_size,
|
||||||
|
B_ANY_KERNEL_BLOCK_ADDRESS | B_MTR_WC,
|
||||||
|
B_READ_AREA | B_WRITE_AREA, &(si->dma_buffer));
|
||||||
|
/* if failed with write combining try again without */
|
||||||
|
if (si->dma_area < 0) {
|
||||||
|
si->dma_area = map_physical_memory(
|
||||||
|
"NV aligned DMA cmd buffer", si->dma_buffer_pci, net_buf_size,
|
||||||
|
B_ANY_KERNEL_BLOCK_ADDRESS,
|
||||||
|
B_READ_AREA | B_WRITE_AREA, &(si->dma_buffer));
|
||||||
|
}
|
||||||
|
/* if there was an error, delete our other areas and pass on error*/
|
||||||
|
if (si->dma_area < 0)
|
||||||
|
{
|
||||||
|
/* free the already created areas, and return the error */
|
||||||
|
result = si->dma_area;
|
||||||
|
goto free_shared_and_uadma;
|
||||||
|
}
|
||||||
|
|
||||||
/* save the vendor and device IDs */
|
/* save the vendor and device IDs */
|
||||||
si->vendor_id = di->pcii.vendor_id;
|
si->vendor_id = di->pcii.vendor_id;
|
||||||
@@ -938,7 +957,7 @@ static status_t open_hook (const char* name, uint32 flags, void** cookie) {
|
|||||||
|
|
||||||
/* map the device */
|
/* map the device */
|
||||||
result = map_device(di);
|
result = map_device(di);
|
||||||
if (result < 0) goto free_shared_and_dma;
|
if (result < 0) goto free_shared_and_alldma;
|
||||||
result = B_OK;
|
result = B_OK;
|
||||||
|
|
||||||
/* create a semaphore for vertical blank management */
|
/* create a semaphore for vertical blank management */
|
||||||
@@ -995,11 +1014,17 @@ delete_the_sem:
|
|||||||
unmap:
|
unmap:
|
||||||
unmap_device(di);
|
unmap_device(di);
|
||||||
|
|
||||||
free_shared_and_dma:
|
free_shared_and_alldma:
|
||||||
/* clean up our DMA area */
|
/* clean up our aligned DMA area */
|
||||||
delete_area(si->dma_buffer_area);
|
delete_area(si->dma_area);
|
||||||
si->dma_buffer_area = -1;
|
si->dma_area = -1;
|
||||||
si->dma_buffer = si->dma_buffer_pci = si->engine.dma.cmdbuffer = NULL;
|
si->dma_buffer = NULL;
|
||||||
|
|
||||||
|
free_shared_and_uadma:
|
||||||
|
/* clean up our unaligned DMA area */
|
||||||
|
delete_area(si->unaligned_dma_area);
|
||||||
|
si->unaligned_dma_area = -1;
|
||||||
|
si->dma_buffer_pci = NULL;
|
||||||
|
|
||||||
free_shared:
|
free_shared:
|
||||||
/* clean up our shared area */
|
/* clean up our shared area */
|
||||||
@@ -1074,10 +1099,15 @@ free_hook (void* dev) {
|
|||||||
/* free regs and framebuffer areas */
|
/* free regs and framebuffer areas */
|
||||||
unmap_device(di);
|
unmap_device(di);
|
||||||
|
|
||||||
/* clean up our DMA area */
|
/* clean up our aligned DMA area */
|
||||||
delete_area(si->dma_buffer_area);
|
delete_area(si->dma_area);
|
||||||
si->dma_buffer_area = -1;
|
si->dma_area = -1;
|
||||||
si->dma_buffer = si->dma_buffer_pci = si->engine.dma.cmdbuffer = NULL;
|
si->dma_buffer = NULL;
|
||||||
|
|
||||||
|
/* clean up our unaligned DMA area */
|
||||||
|
delete_area(si->unaligned_dma_area);
|
||||||
|
si->unaligned_dma_area = -1;
|
||||||
|
si->dma_buffer_pci = NULL;
|
||||||
|
|
||||||
/* clean up our shared area */
|
/* clean up our shared area */
|
||||||
delete_area(di->shared_area);
|
delete_area(di->shared_area);
|
||||||
|
|||||||
Reference in New Issue
Block a user