diff options
-rw-r--r-- | shared-core/nouveau_fifo.c | 2 | ||||
-rw-r--r-- | shared-core/nouveau_mem.c | 2 | ||||
-rw-r--r-- | shared-core/nouveau_object.c | 39 |
3 files changed, 36 insertions, 7 deletions
diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index 88f66d70..7bcb1c8f 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -217,7 +217,7 @@ nouveau_fifo_cmdbuf_alloc(struct drm_device *dev, int channel) cb->size, NV_DMA_ACCESS_RO, NV_DMA_TARGET_AGP, &pushbuf); } else if ( cb->flags & NOUVEAU_MEM_PCI) { - DRM_DEBUG("Creating CB in PCI memory\n", cb->start, cb->size); + DRM_DEBUG("Creating CB in PCI memory\n"); ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, cb->start, diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index a428b813..790f6b5b 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -549,6 +549,8 @@ int nouveau_ioctl_mem_free(DRM_IOCTL_ARGS) block = find_block(dev_priv->fb_heap, memfree.region_offset); else if (memfree.flags&NOUVEAU_MEM_AGP) block = find_block(dev_priv->agp_heap, memfree.region_offset); + else if (memfree.flags&NOUVEAU_MEM_PCI) + block = find_block(dev_priv->pci_heap, memfree.region_offset); if (!block) return DRM_ERR(EFAULT); if (block->filp != filp) diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 0fe32fda..4f7ad111 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -635,10 +635,10 @@ nouveau_gpuobj_dma_new(drm_device_t *dev, int channel, int class, else { uint32_t instance_offset; - uint32_t bus_addr; + uint64_t bus_addr; size = (uint32_t) size; - DRM_DEBUG("Creating PCI DMA object using virtual zone starting at 0x%08x, size %d\n", (uint32_t) offset, (uint32_t)size); + DRM_DEBUG("Creating PCI DMA object using virtual zone starting at %#llx, size %d\n", offset, (uint32_t)size); INSTANCE_WR(*gpuobj, 0, ((1<<12) | (0<<13) | (adjust << 20) | (access << 14) | @@ -651,10 +651,37 @@ nouveau_gpuobj_dma_new(drm_device_t *dev, int channel, int class, /*for each PAGE, get its bus address, fill in the page table entry, and advance*/ while ( size > 0 ) { - bus_addr = (uint32_t) page_address(vmalloc_to_page((void *) (uint32_t) offset)); + bus_addr = vmalloc_to_page(offset); + if ( ! bus_addr ) + { + DRM_ERROR("Couldn't map virtual address %#llx to a page number\n", offset); + nouveau_gpuobj_del(dev, gpuobj); + return DRM_ERR(ENOMEM); + } + bus_addr = (uint64_t) page_address(bus_addr); + if ( ! bus_addr ) + { + DRM_ERROR("Couldn't find page address for address %#llx\n", offset); + nouveau_gpuobj_del(dev, gpuobj); + return DRM_ERR(ENOMEM); + } bus_addr |= (offset & ~PAGE_MASK); bus_addr = virt_to_bus((void *)bus_addr); - frame = bus_addr & ~0x00000FFF; + if ( ! bus_addr ) + { + DRM_ERROR("Couldn't get bus address for %#llx\n", offset); + nouveau_gpuobj_del(dev, gpuobj); + return DRM_ERR(ENOMEM); + } + + /*if ( bus_addr >= 1 << 32 ) + { + DRM_ERROR("Bus address %#llx is over 32 bits, Nvidia cards cannot address it !\n", bus_addr); + nouveau_gpuobj_del(dev, gpuobj); + return DRM_ERR(EINVAL); + }*/ + + frame = (uint32_t) bus_addr & ~0x00000FFF; INSTANCE_WR(*gpuobj, instance_offset, frame | pte_flags); offset += PAGE_SIZE; instance_offset ++; @@ -894,11 +921,11 @@ nouveau_gpuobj_channel_init(drm_device_t *dev, int channel, /*PCI*/ if((ret = nouveau_gpuobj_dma_new(dev, channel, NV_CLASS_DMA_IN_MEMORY, - (unsigned int) dev->sg->virtual, dev->sg->pages * PAGE_SIZE, + dev->sg->virtual, dev->sg->pages * PAGE_SIZE, NV_DMA_ACCESS_RW, NV_DMA_TARGET_PCI_NONLINEAR, &tt))) { DRM_ERROR("Error creating PCI TT ctxdma: %d\n", DRM_ERR(ENOMEM)); - return DRM_ERR(ENOMEM); + return 0; //this is noncritical } ret = nouveau_gpuobj_ref_add(dev, channel, tt_h, tt, NULL); |