summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c')
-rw-r--r--drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c b/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c
new file mode 100644
index 00000000..f8feb6a2
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/posix/posix-nvgpu_mem.c
@@ -0,0 +1,209 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <nvgpu/bug.h>
24#include <nvgpu/dma.h>
25#include <nvgpu/gmmu.h>
26#include <nvgpu/kmem.h>
27#include <nvgpu/nvgpu_mem.h>
28
29/*
30 * DMA memory buffers - obviously we don't really have DMA in userspace but we
31 * can emulate a lot of the DMA mem functionality for unit testing purposes.
32 */
33
34int nvgpu_mem_begin(struct gk20a *g, struct nvgpu_mem *mem)
35{
36 return 0;
37}
38
39void nvgpu_mem_end(struct gk20a *g, struct nvgpu_mem *mem)
40{
41 return;
42}
43
44u32 nvgpu_mem_rd32(struct gk20a *g, struct nvgpu_mem *mem, u32 w)
45{
46 u32 *mem_ptr = (u32 *)mem->cpu_va;
47
48 return mem_ptr[w];
49}
50
51u32 nvgpu_mem_rd(struct gk20a *g, struct nvgpu_mem *mem, u32 offset)
52{
53 if (offset & 0x3)
54 BUG();
55
56 return nvgpu_mem_rd32(g, mem, offset >> 2);
57}
58
59void nvgpu_mem_rd_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset,
60 void *dest, u32 size)
61{
62 if (offset & 0x3 || size & 0x3)
63 BUG();
64
65 memcpy(dest, ((char *)mem->cpu_va) + offset, size);
66}
67
68void nvgpu_mem_wr32(struct gk20a *g, struct nvgpu_mem *mem, u32 w, u32 data)
69{
70 u32 *mem_ptr = (u32 *)mem->cpu_va;
71
72 mem_ptr[w] = data;
73}
74
75void nvgpu_mem_wr(struct gk20a *g, struct nvgpu_mem *mem, u32 offset, u32 data)
76{
77 if (offset & 0x3)
78 BUG();
79
80 nvgpu_mem_wr32(g, mem, offset >> 2, data);
81}
82
83void nvgpu_mem_wr_n(struct gk20a *g, struct nvgpu_mem *mem, u32 offset,
84 void *src, u32 size)
85{
86 if (offset & 0x3 || size & 0x3)
87 BUG();
88
89 memcpy(((char *)mem->cpu_va) + offset, src, size);
90}
91
92void nvgpu_memset(struct gk20a *g, struct nvgpu_mem *mem, u32 offset,
93 u32 c, u32 size)
94{
95 memset(((char *)mem->cpu_va) + offset, c, size);
96}
97
98/*
99 * These functions are somewhat meaningless.
100 */
101u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem)
102{
103 return (u64)(uintptr_t)mem->cpu_va;
104}
105
106u64 nvgpu_mem_get_phys_addr(struct gk20a *g, struct nvgpu_mem *mem)
107{
108 return (u64)(uintptr_t)mem->cpu_va;
109}
110
111static struct nvgpu_sgl *nvgpu_mem_sgl_next(struct nvgpu_sgl *sgl)
112{
113 return NULL;
114}
115
116static u64 nvgpu_mem_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl)
117{
118 struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl;
119
120 return (u64)(uintptr_t)mem->cpu_va;
121}
122
123static u64 nvgpu_mem_sgl_dma(struct nvgpu_sgl *sgl)
124{
125 struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl;
126
127 return (u64)(uintptr_t)mem->cpu_va;
128}
129
130static u64 nvgpu_mem_sgl_length(struct nvgpu_sgl *sgl)
131{
132 struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl;
133
134 return (u64)mem->aligned_size;
135}
136
137static u64 nvgpu_mem_sgl_gpu_addr(struct gk20a *g, struct nvgpu_sgl *sgl,
138 struct nvgpu_gmmu_attrs *attrs)
139{
140 struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl;
141
142 return mem->gpu_va;
143}
144
145static bool nvgpu_mem_sgt_iommuable(struct gk20a *g, struct nvgpu_sgt *sgt)
146{
147 return nvgpu_iommuable(g);
148}
149
150static void nvgpu_mem_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt)
151{
152 nvgpu_kfree(g, sgt);
153}
154
155static struct nvgpu_sgt_ops nvgpu_sgt_posix_ops = {
156 .sgl_next = nvgpu_mem_sgl_next,
157 .sgl_phys = nvgpu_mem_sgl_phys,
158 .sgl_dma = nvgpu_mem_sgl_dma,
159 .sgl_length = nvgpu_mem_sgl_length,
160 .sgl_gpu_addr = nvgpu_mem_sgl_gpu_addr,
161 .sgt_iommuable = nvgpu_mem_sgt_iommuable,
162 .sgt_free = nvgpu_mem_sgt_free,
163};
164
165struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g,
166 struct nvgpu_mem *mem)
167{
168 struct nvgpu_sgt *sgt = nvgpu_kzalloc(g, sizeof(*sgt));
169
170 if (sgt == NULL)
171 return NULL;
172
173 /*
174 * The userspace implementation is simple: a single 'entry' (which we
175 * only need the mem struct to describe). Maybe this could be expanded
176 * to be more interesting some day.
177 */
178 sgt->sgl = (struct nvgpu_sgl *)mem;
179 sgt->ops = &nvgpu_sgt_posix_ops;
180
181 return sgt;
182}
183
184int nvgpu_mem_create_from_mem(struct gk20a *g,
185 struct nvgpu_mem *dest, struct nvgpu_mem *src,
186 int start_page, int nr_pages)
187{
188 u64 start = start_page * PAGE_SIZE;
189 u64 size = nr_pages * PAGE_SIZE;
190
191 if (src->aperture != APERTURE_SYSMEM)
192 return -EINVAL;
193
194 /* Some silly things a caller might do... */
195 if (size > src->size)
196 return -EINVAL;
197 if ((start + size) > src->size)
198 return -EINVAL;
199
200 memset(dest, 0, sizeof(*dest));
201
202 dest->cpu_va = ((char *)src->cpu_va) + start;
203 dest->mem_flags = src->mem_flags | NVGPU_MEM_FLAG_SHADOW_COPY;
204 dest->aperture = src->aperture;
205 dest->skip_wmb = src->skip_wmb;
206 dest->size = size;
207
208 return 0;
209}