* the alignment determined by gmmu_select_page_size().
*/
if (flags & NVGPU_AS_MAP_BUFFER_FLAGS_FIXED_OFFSET) {
- int pgsz_idx = NV_GMMU_VA_IS_UPPER(offset_align) ?
+ int pgsz_idx = __nv_gmmu_va_is_upper(vm, offset_align) ?
gmmu_page_size_big : gmmu_page_size_small;
if (pgsz_idx > bfr.pgsz_idx) {
gk20a_err(d, "%llx buffer pgsz %d, VA pgsz %d",
/* note: keep the page sizes sorted lowest to highest here */
u32 gmmu_page_sizes[gmmu_nr_page_sizes] = { SZ_4K, big_page_size };
+ /*
+ * Linsim bug: seems like we can't have pushbuffers above 4GB. Easy WAR for sim
+ * is to just limit the address space to 4GB.
+ */
+ if (tegra_platform_is_linsim() && aperture_size > SZ_4G)
+ aperture_size = SZ_4G;
+
vm->mm = mm;
vm->va_start = low_hole;
* remains is allocated to large pages. */
small_vma_size = vm->va_limit;
if (big_pages) {
- small_vma_size = (u64)16 << 30;
+ small_vma_size = __nv_gmmu_va_small_page_limit();
large_vma_size = vm->va_limit - small_vma_size;
}
args->pages, args->offset);
/* determine pagesz idx */
- pgsz_idx = NV_GMMU_VA_IS_UPPER(args->offset) ?
+ pgsz_idx = __nv_gmmu_va_is_upper(vm, args->offset) ?
gmmu_page_size_big : gmmu_page_size_small;
start_page_nr = (u32)(args->offset >>
#include <linux/scatterlist.h>
#include <linux/dma-attrs.h>
#include <linux/iommu.h>
+#include <linux/tegra-soc.h>
#include <asm/dma-iommu.h>
#include <asm/cacheflush.h>
#include "gk20a_allocator.h"
-/*
- * Amount of the GVA space we actually use is smaller than the available space.
- * The bottom 16GB of the space are used for small pages, the remaining high
- * memory is for large pages.
- */
-#define NV_GMMU_VA_RANGE 37ULL
-#define NV_GMMU_VA_IS_UPPER(x) ((x) >= ((u64)SZ_1G * 16))
-
#ifdef CONFIG_ARM64
#define outer_flush_range(a, b)
#define __cpuc_flush_dcache_area __flush_dcache_area
return 40; /* chopped for area? */
}
+/*
+ * Amount of the GVA space we actually use is smaller than the available space.
+ */
+#define NV_GMMU_VA_RANGE 37
+
+/*
+ * The bottom 16GB of the space are used for small pages, the remaining high
+ * memory is for large pages. On simulation use 2GB for small pages, 2GB for
+ * large pages (if enabled).
+ */
+static inline u64 __nv_gmmu_va_small_page_limit(void)
+{
+ if (tegra_platform_is_linsim())
+ return ((u64)SZ_1G * 2);
+ else
+ return ((u64)SZ_1G * 16);
+}
+
+static inline int __nv_gmmu_va_is_upper(struct vm_gk20a *vm, u64 addr)
+{
+ if (!vm->big_pages)
+ return 0;
+
+ return addr >= __nv_gmmu_va_small_page_limit();
+}
+
+/*
+ * This determines the PTE size for a given alloc. Used by both the GVA space
+ * allocator and the mm core code so that agreement can be reached on how to
+ * map allocations.
+ */
+static inline enum gmmu_pgsz_gk20a __get_pte_size(struct vm_gk20a *vm,
+ u64 base, u64 size)
+{
+ /*
+ * Currently userspace is not ready for a true unified address space.
+ * As a result, even though the allocator supports mixed address spaces
+ * the address spaces must be treated as separate for now.
+ */
+ if (__nv_gmmu_va_is_upper(vm, base))
+ return gmmu_page_size_big;
+ else
+ return gmmu_page_size_small;
+}
+
#if 0 /*related to addr bits above, concern below TBD on which is accurate */
#define bar1_instance_block_shift_gk20a() (max_physaddr_bits_gk20a() -\
bus_bar1_block_ptr_s())