From b15624b39b9b19ba139776e2a917bcd4e361c01e Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Wed, 15 Aug 2018 16:32:37 -0700 Subject: gpu: nvgpu: posix: move the posix dir to os Since the posix code is supporting a particular OS this code should belong under os/ not common/. Change-Id: Idf5f75b8ab9d614c9dd43ea23dab8df3c346c0ef Signed-off-by: Alex Waterman Reviewed-on: https://git-master.nvidia.com/r/1800658 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/os/posix/bitmap.c | 216 +++++++++++++++++++++++++ drivers/gpu/nvgpu/os/posix/bug.c | 67 ++++++++ drivers/gpu/nvgpu/os/posix/channel.c | 32 ++++ drivers/gpu/nvgpu/os/posix/clk_arb.c | 149 +++++++++++++++++ drivers/gpu/nvgpu/os/posix/cond.c | 55 +++++++ drivers/gpu/nvgpu/os/posix/dma.c | 228 +++++++++++++++++++++++++++ drivers/gpu/nvgpu/os/posix/error_notifier.c | 40 +++++ drivers/gpu/nvgpu/os/posix/firmware.c | 35 ++++ drivers/gpu/nvgpu/os/posix/fuse.c | 54 +++++++ drivers/gpu/nvgpu/os/posix/io.c | 87 ++++++++++ drivers/gpu/nvgpu/os/posix/kmem.c | 134 ++++++++++++++++ drivers/gpu/nvgpu/os/posix/lock.c | 79 ++++++++++ drivers/gpu/nvgpu/os/posix/log.c | 95 +++++++++++ drivers/gpu/nvgpu/os/posix/nvgpu.c | 144 +++++++++++++++++ drivers/gpu/nvgpu/os/posix/nvlink.c | 33 ++++ drivers/gpu/nvgpu/os/posix/os_posix.h | 32 ++++ drivers/gpu/nvgpu/os/posix/posix-comptags.c | 49 ++++++ drivers/gpu/nvgpu/os/posix/posix-nvgpu_mem.c | 140 ++++++++++++++++ drivers/gpu/nvgpu/os/posix/posix-vm.c | 52 ++++++ drivers/gpu/nvgpu/os/posix/rwsem.c | 117 ++++++++++++++ drivers/gpu/nvgpu/os/posix/soc.c | 53 +++++++ drivers/gpu/nvgpu/os/posix/stubs.c | 49 ++++++ drivers/gpu/nvgpu/os/posix/thread.c | 96 +++++++++++ drivers/gpu/nvgpu/os/posix/timers.c | 169 ++++++++++++++++++++ drivers/gpu/nvgpu/os/posix/tsg.c | 28 ++++ 25 files changed, 2233 insertions(+) create mode 100644 drivers/gpu/nvgpu/os/posix/bitmap.c create mode 100644 drivers/gpu/nvgpu/os/posix/bug.c create mode 100644 drivers/gpu/nvgpu/os/posix/channel.c create mode 100644 drivers/gpu/nvgpu/os/posix/clk_arb.c create mode 100644 drivers/gpu/nvgpu/os/posix/cond.c create mode 100644 drivers/gpu/nvgpu/os/posix/dma.c create mode 100644 drivers/gpu/nvgpu/os/posix/error_notifier.c create mode 100644 drivers/gpu/nvgpu/os/posix/firmware.c create mode 100644 drivers/gpu/nvgpu/os/posix/fuse.c create mode 100644 drivers/gpu/nvgpu/os/posix/io.c create mode 100644 drivers/gpu/nvgpu/os/posix/kmem.c create mode 100644 drivers/gpu/nvgpu/os/posix/lock.c create mode 100644 drivers/gpu/nvgpu/os/posix/log.c create mode 100644 drivers/gpu/nvgpu/os/posix/nvgpu.c create mode 100644 drivers/gpu/nvgpu/os/posix/nvlink.c create mode 100644 drivers/gpu/nvgpu/os/posix/os_posix.h create mode 100644 drivers/gpu/nvgpu/os/posix/posix-comptags.c create mode 100644 drivers/gpu/nvgpu/os/posix/posix-nvgpu_mem.c create mode 100644 drivers/gpu/nvgpu/os/posix/posix-vm.c create mode 100644 drivers/gpu/nvgpu/os/posix/rwsem.c create mode 100644 drivers/gpu/nvgpu/os/posix/soc.c create mode 100644 drivers/gpu/nvgpu/os/posix/stubs.c create mode 100644 drivers/gpu/nvgpu/os/posix/thread.c create mode 100644 drivers/gpu/nvgpu/os/posix/timers.c create mode 100644 drivers/gpu/nvgpu/os/posix/tsg.c (limited to 'drivers/gpu/nvgpu/os') diff --git a/drivers/gpu/nvgpu/os/posix/bitmap.c b/drivers/gpu/nvgpu/os/posix/bitmap.c new file mode 100644 index 00000000..f25f6e64 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/bitmap.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include +#include + +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) + +unsigned long __nvgpu_posix_ffs(unsigned long word) +{ + return (__builtin_ffsl(word) - 1) & + ((sizeof(unsigned long) * 8UL) - 1UL); +} + +unsigned long __nvgpu_posix_fls(unsigned long word) +{ + return ((sizeof(unsigned long) * 8UL) - 1UL) - __builtin_clzl(word); +} + +static unsigned long __find_next_bit(const unsigned long *addr, + unsigned long n, + unsigned long start, + bool invert) +{ + unsigned long idx; + unsigned long w; + unsigned long start_mask; + + /* + * We make a mask we can XOR into the word so that we can invert the + * word without requiring a branch. I.e instead of doing: + * + * w = invert ? ~addr[idx] : addr[idx] + * + * We can do: + * + * w = addr[idx] ^= invert_mask + * + * This saves us a branch every iteration through the loop. Now we can + * always just look for 1s. + */ + unsigned long invert_mask = invert ? ~0UL : 0UL; + + if (start >= n) + return n; + + start_mask = ~0UL << (start & (BITS_PER_LONG - 1)); + + idx = start / BITS_PER_LONG; + w = (addr[idx] ^ invert_mask) & start_mask; + + start = round_up(start, BITS_PER_LONG); + + /* + * Find the first non-zero word taking into account start and + * invert. + */ + while (!w) { + idx++; + start += BITS_PER_LONG; + + w = addr[idx] ^ invert_mask; + } + + return min(n, ffs(w) + idx * BITS_PER_LONG); +} + +unsigned long find_first_bit(const unsigned long *addr, unsigned long size) +{ + return __find_next_bit(addr, size, 0, false); +} + +unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) +{ + return __find_next_bit(addr, size, 0, true); +} + +unsigned long find_next_bit(const unsigned long *addr, unsigned long size, + unsigned long offset) +{ + return __find_next_bit(addr, size, offset, false); +} + +static unsigned long find_next_zero_bit(const unsigned long *addr, + unsigned long size, + unsigned long offset) +{ + return __find_next_bit(addr, size, offset, true); +} + +void bitmap_set(unsigned long *map, unsigned int start, int len) +{ + unsigned int end = start + len; + + /* + * Super slow naive implementation. But speed isn't what matters here. + */ + while (start < end) + set_bit(start++, map); +} + +void bitmap_clear(unsigned long *map, unsigned int start, int len) +{ + unsigned int end = start + len; + + while (start < end) + clear_bit(start++, map); +} + +/* + * This is essentially a find-first-fit allocator: this searches a bitmap for + * the first space that is large enough to satisfy the requested size of bits. + * That means that this is not a vary smart allocator. But it is fast relative + * to an allocator that goes looking for an optimal location. + */ +unsigned long bitmap_find_next_zero_area_off(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask, + unsigned long align_offset) +{ + unsigned long offs; + + while (start + nr <= size) { + start = find_next_zero_bit(map, size, start); + + start = ALIGN_MASK(start + align_offset, align_mask) - + align_offset; + + /* + * Not enough space left to satisfy the requested area. + */ + if ((start + nr) > size) + return size; + + offs = find_next_bit(map, size, start); + + if ((offs - start) >= nr) + return start; + + start = offs + 1; + } + + return size; +} + +unsigned long bitmap_find_next_zero_area(unsigned long *map, + unsigned long size, + unsigned long start, + unsigned int nr, + unsigned long align_mask) +{ + return bitmap_find_next_zero_area_off(map, size, start, nr, + align_mask, 0); +} + +bool test_bit(int nr, const volatile unsigned long *addr) +{ + return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); +} + +bool test_and_set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + volatile unsigned long *p = addr + BIT_WORD(nr); + + return !!(__sync_fetch_and_or(p, mask) & mask); +} + +bool test_and_clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + return !!(__sync_fetch_and_and(p, ~mask) & mask); +} + +void set_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + __atomic_or(p, mask); +} + +void clear_bit(int nr, volatile unsigned long *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + __atomic_and(p, ~mask); +} diff --git a/drivers/gpu/nvgpu/os/posix/bug.c b/drivers/gpu/nvgpu/os/posix/bug.c new file mode 100644 index 00000000..64f4a6f6 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/bug.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include + +__attribute__ ((noreturn)) +static void __hang(void) +{ + nvgpu_err(NULL, "Hanging!"); + + while (1) + ; +} + +static void __dump_stack(unsigned int skip_frames) +{ + return; +} + +void dump_stack(void) +{ + __dump_stack(0); +} + +/* + * Ahhh! A bug! + */ +void __bug(const char *fmt, ...) +{ + nvgpu_err(NULL, "BUG detected!"); + + __hang(); +} + +bool __warn(bool cond, const char *fmt, ...) +{ + if (!cond) + goto done; + + nvgpu_warn(NULL, "WARNING detected!"); + + dump_stack(); + +done: + return cond; +} diff --git a/drivers/gpu/nvgpu/os/posix/channel.c b/drivers/gpu/nvgpu/os/posix/channel.c new file mode 100644 index 00000000..05697159 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/channel.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "gk20a/channel_gk20a.h" + +u32 nvgpu_get_gpfifo_entry_size(void) +{ + /* + * There is no struct nvgpu_gpfifo for us to use yet. But when it's + * defined in userspace this is how big it will be. + */ + return 8; +} diff --git a/drivers/gpu/nvgpu/os/posix/clk_arb.c b/drivers/gpu/nvgpu/os/posix/clk_arb.c new file mode 100644 index 00000000..2214b37b --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/clk_arb.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/** + * Stub imlementation of the clk_arb code. Yikes. Much of this probably could be + * commonized if one were to think through the implementation but that is + * probably weeks of work at a minimum. + * + * So for POSIX it will be stubbed. + */ + +int nvgpu_clk_arb_init_arbiter(struct gk20a *g) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, + u16 *min_mhz, u16 *max_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, + u32 api_domain, u16 *actual_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, + u32 api_domain, u16 *effective_mhz) +{ + return -ENOSYS; +} + + +int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, + u32 api_domain, + u32 *max_points, u16 *fpoints) +{ + return -ENOSYS; +} + +u32 nvgpu_clk_arb_get_arbiter_clk_domains(struct gk20a *g) +{ + return 0; +} + +bool nvgpu_clk_arb_is_valid_domain(struct gk20a *g, u32 api_domain) +{ + return false; +} + +void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g) +{ +} + +int nvgpu_clk_arb_install_session_fd(struct gk20a *g, + struct nvgpu_clk_session *session) +{ + return -ENOSYS; +} + + +int nvgpu_clk_arb_init_session(struct gk20a *g, + struct nvgpu_clk_session **_session) +{ + return -ENOSYS; +} + +void nvgpu_clk_arb_release_session(struct gk20a *g, + struct nvgpu_clk_session *session) +{ +} + +int nvgpu_clk_arb_commit_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int request_fd) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_set_session_target_mhz(struct nvgpu_clk_session *session, + int fd, u32 api_domain, u16 target_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, + u32 api_domain, u16 *target_mhz) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_install_event_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int *event_fd, u32 alarm_mask) +{ + return -ENOSYS; +} + +int nvgpu_clk_arb_install_request_fd(struct gk20a *g, + struct nvgpu_clk_session *session, + int *event_fd) +{ + return -ENOSYS; +} + +void nvgpu_clk_arb_schedule_vf_table_update(struct gk20a *g) +{ +} + +int nvgpu_clk_arb_get_current_pstate(struct gk20a *g) +{ + return -ENOSYS; +} + +void nvgpu_clk_arb_pstate_change_lock(struct gk20a *g, bool lock) +{ +} + +void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) +{ +} + +void nvgpu_clk_arb_schedule_alarm(struct gk20a *g, u32 alarm) +{ +} diff --git a/drivers/gpu/nvgpu/os/posix/cond.c b/drivers/gpu/nvgpu/os/posix/cond.c new file mode 100644 index 00000000..ca8a2c4a --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/cond.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include + +int nvgpu_cond_init(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_signal(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_signal_interruptible(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_broadcast(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +int nvgpu_cond_broadcast_interruptible(struct nvgpu_cond *cond) +{ + return -ENOSYS; +} + +void nvgpu_cond_destroy(struct nvgpu_cond *cond) +{ + +} diff --git a/drivers/gpu/nvgpu/os/posix/dma.c b/drivers/gpu/nvgpu/os/posix/dma.c new file mode 100644 index 00000000..95bb1a75 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/dma.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * In userspace vidmem vs sysmem is just a difference in what is placed in the + * aperture field. + */ +static int __nvgpu_do_dma_alloc(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, + enum nvgpu_aperture ap) +{ + void *memory = malloc(mem->aligned_size); + + if (memory == NULL) + return -ENOMEM; + + mem->cpu_va = memory; + mem->aperture = ap; + mem->size = size; + mem->aligned_size = PAGE_ALIGN(size); + mem->gpu_va = 0ULL; + mem->skip_wmb = true; + mem->vidmem_alloc = NULL; + mem->allocator = NULL; + + return 0; +} + +bool nvgpu_iommuable(struct gk20a *g) +{ + return false; +} + +int nvgpu_dma_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_flags(g, 0, size, mem); +} + +int nvgpu_dma_alloc_flags(struct gk20a *g, unsigned long flags, size_t size, + struct nvgpu_mem *mem) +{ + if (!nvgpu_is_enabled(g, NVGPU_MM_UNIFIED_MEMORY)) { + /* + * First try vidmem. Obviously in userspace there's no such + * thing as vidmem per se but we will mark the aperture as + * vidmem. + */ + int err = nvgpu_dma_alloc_flags_vid(g, 0, size, mem); + + if (!err) + return 0; + /* + * Fall back to sysmem (which may then also fail) in case + * vidmem is exhausted. + */ + } + + return nvgpu_dma_alloc_flags_sys(g, flags, size, mem); + +} + +int nvgpu_dma_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_flags_sys(g, 0, size, mem); +} + +int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + return __nvgpu_do_dma_alloc(g, flags, size, mem, APERTURE_SYSMEM); +} + +int nvgpu_dma_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_flags_vid(g, 0, size, mem); +} + +int nvgpu_dma_alloc_flags_vid(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + return __nvgpu_do_dma_alloc(g, flags, size, mem, APERTURE_VIDMEM); +} + +int nvgpu_dma_alloc_vid_at(struct gk20a *g, + size_t size, struct nvgpu_mem *mem, u64 at) +{ + BUG(); + + return 0; +} + +int nvgpu_dma_alloc_flags_vid_at(struct gk20a *g, unsigned long flags, + size_t size, struct nvgpu_mem *mem, u64 at) +{ + BUG(); + + return 0; +} + +void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem) +{ + if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY)) + free(mem->cpu_va); + + memset(mem, 0, sizeof(*mem)); +} + +int nvgpu_dma_alloc_map(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_map_flags(vm, 0, size, mem); +} + +int nvgpu_dma_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + if (!nvgpu_is_enabled(gk20a_from_vm(vm), NVGPU_MM_UNIFIED_MEMORY)) { + int err = nvgpu_dma_alloc_map_flags_vid(vm, + flags | NVGPU_DMA_NO_KERNEL_MAPPING, + size, mem); + + if (!err) + return 0; + /* + * Fall back to sysmem (which may then also fail) in case + * vidmem is exhausted. + */ + } + + return nvgpu_dma_alloc_map_flags_sys(vm, flags, size, mem); +} + +int nvgpu_dma_alloc_map_sys(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_map_flags_sys(vm, 0, size, mem); +} + +int nvgpu_dma_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + int err = nvgpu_dma_alloc_flags_sys(vm->mm->g, flags, size, mem); + + if (err) + return err; + + mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0, + gk20a_mem_flag_none, false, + mem->aperture); + if (!mem->gpu_va) { + err = -ENOMEM; + goto fail_free; + } + + return 0; + +fail_free: + nvgpu_dma_free(vm->mm->g, mem); + return err; +} + +int nvgpu_dma_alloc_map_vid(struct vm_gk20a *vm, size_t size, + struct nvgpu_mem *mem) +{ + return nvgpu_dma_alloc_map_flags_vid(vm, + NVGPU_DMA_NO_KERNEL_MAPPING, size, mem); +} + +int nvgpu_dma_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags, + size_t size, struct nvgpu_mem *mem) +{ + int err = nvgpu_dma_alloc_flags_vid(vm->mm->g, flags, size, mem); + + if (err) + return err; + + mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0, + gk20a_mem_flag_none, false, + mem->aperture); + if (!mem->gpu_va) { + err = -ENOMEM; + goto fail_free; + } + + return 0; + +fail_free: + nvgpu_dma_free(vm->mm->g, mem); + return err; +} + +void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem) +{ + if (mem->gpu_va) + nvgpu_gmmu_unmap(vm, mem, mem->gpu_va); + mem->gpu_va = 0; + + nvgpu_dma_free(vm->mm->g, mem); +} diff --git a/drivers/gpu/nvgpu/os/posix/error_notifier.c b/drivers/gpu/nvgpu/os/posix/error_notifier.c new file mode 100644 index 00000000..50b4f258 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/error_notifier.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error) +{ +} + +void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error) +{ +} + +void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error) +{ +} + +bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier) +{ + return false; +} diff --git a/drivers/gpu/nvgpu/os/posix/firmware.c b/drivers/gpu/nvgpu/os/posix/firmware.c new file mode 100644 index 00000000..aedfef9f --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/firmware.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +struct nvgpu_firmware *nvgpu_request_firmware(struct gk20a *g, + const char *fw_name, + int flags) +{ + return NULL; +} + +void nvgpu_release_firmware(struct gk20a *g, struct nvgpu_firmware *fw) +{ + /* Noop. */ +} diff --git a/drivers/gpu/nvgpu/os/posix/fuse.c b/drivers/gpu/nvgpu/os/posix/fuse.c new file mode 100644 index 00000000..09ec36dc --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/fuse.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +int nvgpu_tegra_get_gpu_speedo_id(struct gk20a *g) +{ + return 0; +} + +void nvgpu_tegra_fuse_write_bypass(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_access_sw(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc0_disable(struct gk20a *g, u32 val) +{ +} + +void nvgpu_tegra_fuse_write_opt_gpu_tpc1_disable(struct gk20a *g, u32 val) +{ +} + +int nvgpu_tegra_fuse_read_gcplex_config_fuse(struct gk20a *g, u32 *val) +{ + return -ENODEV; +} + +int nvgpu_tegra_fuse_read_reserved_calib(struct gk20a *g, u32 *val) +{ + return -ENODEV; +} diff --git a/drivers/gpu/nvgpu/os/posix/io.c b/drivers/gpu/nvgpu/os/posix/io.c new file mode 100644 index 00000000..7bab8af6 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/io.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +/* + * For now none of these make sense to execute in userspace. Eventually we + * may want to use these to verify certain register read/write sequences + * but for now, just hang. + */ + +void nvgpu_writel(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} + +void nvgpu_writel_relaxed(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} + +u32 nvgpu_readl(struct gk20a *g, u32 r) +{ + BUG(); + + return 0; +} + +u32 __nvgpu_readl(struct gk20a *g, u32 r) +{ + BUG(); + + return 0; +} + +void nvgpu_writel_loop(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} + +void nvgpu_bar1_writel(struct gk20a *g, u32 b, u32 v) +{ + BUG(); +} + +u32 nvgpu_bar1_readl(struct gk20a *g, u32 b) +{ + BUG(); + + return 0; +} + +bool nvgpu_io_exists(struct gk20a *g) +{ + return false; +} + +bool nvgpu_io_valid_reg(struct gk20a *g, u32 r) +{ + return false; +} + +void nvgpu_usermode_writel(struct gk20a *g, u32 r, u32 v) +{ + BUG(); +} diff --git a/drivers/gpu/nvgpu/os/posix/kmem.c b/drivers/gpu/nvgpu/os/posix/kmem.c new file mode 100644 index 00000000..5fe0aeb2 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/kmem.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include + +#include + +struct nvgpu_kmem_cache { + size_t alloc_size; +}; + +/* + * kmem cache emulation: basically just do a regular malloc(). This is slower + * but should not affect a user of kmem cache in the slightest bit. + */ +struct nvgpu_kmem_cache *nvgpu_kmem_cache_create(struct gk20a *g, size_t size) +{ + struct nvgpu_kmem_cache *cache = + malloc(sizeof(struct nvgpu_kmem_cache)); + + if (cache != NULL) + return NULL; + + cache->alloc_size = size; + + return cache; +} + +void nvgpu_kmem_cache_destroy(struct nvgpu_kmem_cache *cache) +{ + free(cache); +} + +void *nvgpu_kmem_cache_alloc(struct nvgpu_kmem_cache *cache) +{ + return malloc(cache->alloc_size); +} + +void nvgpu_kmem_cache_free(struct nvgpu_kmem_cache *cache, void *ptr) +{ + free(ptr); +} + +void *__nvgpu_kmalloc(struct gk20a *g, size_t size, void *ip) +{ + return malloc(size); +} + +void *__nvgpu_kzalloc(struct gk20a *g, size_t size, void *ip) +{ + return calloc(1, size); +} + +void *__nvgpu_kcalloc(struct gk20a *g, size_t n, size_t size, void *ip) +{ + /* + * calloc() implicitly zeros mem. So calloc a single member size bytes + * long. + */ + return calloc(n, size); +} + +void __nvgpu_kfree(struct gk20a *g, void *addr) +{ + free(addr); +} + +/* + * The concept of vmalloc() does not exist in userspace. + */ +void *__nvgpu_vmalloc(struct gk20a *g, unsigned long size, void *ip) +{ + return __nvgpu_kmalloc(g, size, ip); +} + +void *__nvgpu_vzalloc(struct gk20a *g, unsigned long size, void *ip) +{ + return __nvgpu_kzalloc(g, size, ip); +} + +void __nvgpu_vfree(struct gk20a *g, void *addr) +{ + __nvgpu_kfree(g, addr); +} + +void *__nvgpu_big_alloc(struct gk20a *g, size_t size, bool clear) +{ + /* + * Since in userspace vmalloc() == kmalloc() == malloc() we can just + * reuse k[zm]alloc() for this. + */ + return clear ? + __nvgpu_kzalloc(g, size, _NVGPU_GET_IP_) : + __nvgpu_kmalloc(g, size, _NVGPU_GET_IP_); +} + +void nvgpu_big_free(struct gk20a *g, void *p) +{ + __nvgpu_kfree(g, p); +} + +int nvgpu_kmem_init(struct gk20a *g) +{ + /* Nothing to init at the moment. */ + return 0; +} + +void nvgpu_kmem_fini(struct gk20a *g, int flags) +{ + +} diff --git a/drivers/gpu/nvgpu/os/posix/lock.c b/drivers/gpu/nvgpu/os/posix/lock.c new file mode 100644 index 00000000..bca0f04c --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/lock.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +int nvgpu_mutex_init(struct nvgpu_mutex *mutex) +{ + return pthread_mutex_init(&mutex->lock.mutex, NULL); +} + +void nvgpu_mutex_acquire(struct nvgpu_mutex *mutex) +{ + __nvgpu_posix_lock_acquire(&mutex->lock); +} + +void nvgpu_mutex_release(struct nvgpu_mutex *mutex) +{ + __nvgpu_posix_lock_release(&mutex->lock); +} + +int nvgpu_mutex_tryacquire(struct nvgpu_mutex *mutex) +{ + return __nvgpu_posix_lock_try_acquire(&mutex->lock); +} + +void nvgpu_mutex_destroy(struct nvgpu_mutex *mutex) +{ + pthread_mutex_destroy(&mutex->lock.mutex); +} + +void nvgpu_spinlock_init(struct nvgpu_spinlock *spinlock) +{ + pthread_mutex_init(&spinlock->lock.mutex, NULL); +} + +void nvgpu_spinlock_acquire(struct nvgpu_spinlock *spinlock) +{ + __nvgpu_posix_lock_acquire(&spinlock->lock); +} + +void nvgpu_spinlock_release(struct nvgpu_spinlock *spinlock) +{ + __nvgpu_posix_lock_release(&spinlock->lock); +} + +void nvgpu_raw_spinlock_init(struct nvgpu_raw_spinlock *spinlock) +{ + pthread_mutex_init(&spinlock->lock.mutex, NULL); +} + +void nvgpu_raw_spinlock_acquire(struct nvgpu_raw_spinlock *spinlock) +{ + __nvgpu_posix_lock_acquire(&spinlock->lock); +} + +void nvgpu_raw_spinlock_release(struct nvgpu_raw_spinlock *spinlock) +{ + __nvgpu_posix_lock_release(&spinlock->lock); +} diff --git a/drivers/gpu/nvgpu/os/posix/log.c b/drivers/gpu/nvgpu/os/posix/log.c new file mode 100644 index 00000000..6bfb673c --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/log.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "gk20a/gk20a.h" + +/* + * Define a length for log buffers. This is the buffer that the 'fmt, ...' part + * of __nvgpu_do_log_print() prints into. + */ +#define LOG_BUFFER_LENGTH 160 + +/* + * Keep this roughly the same as the kernel log format. + */ +#define LOG_FMT "nvgpu: %s %33s:%-4d [%-4s] %s\n" + +u64 nvgpu_dbg_mask = NVGPU_DEFAULT_DBG_MASK; + +static const char *log_types[] = { + "ERR", + "WRN", + "DBG", + "INFO", +}; + +static inline const char *nvgpu_log_name(struct gk20a *g) +{ + return "gpu.USS"; +} + +static void __nvgpu_really_print_log(const char *gpu_name, + const char *func_name, int line, + enum nvgpu_log_type type, const char *log) +{ + const char *name = gpu_name ? gpu_name : ""; + const char *log_type = log_types[type]; + + printf(LOG_FMT, name, func_name, line, log_type, log); +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_msg(struct gk20a *g, const char *func_name, int line, + enum nvgpu_log_type type, const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(nvgpu_log_name(g), + func_name, line, type, log); +} + +__attribute__((format (printf, 5, 6))) +void __nvgpu_log_dbg(struct gk20a *g, u64 log_mask, + const char *func_name, int line, + const char *fmt, ...) +{ + char log[LOG_BUFFER_LENGTH]; + va_list args; + + if ((log_mask & g->log_mask) == 0) + return; + + va_start(args, fmt); + vsnprintf(log, LOG_BUFFER_LENGTH, fmt, args); + va_end(args); + + __nvgpu_really_print_log(nvgpu_log_name(g), + func_name, line, NVGPU_DEBUG, log); +} diff --git a/drivers/gpu/nvgpu/os/posix/nvgpu.c b/drivers/gpu/nvgpu/os/posix/nvgpu.c new file mode 100644 index 00000000..a275f2de --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/nvgpu.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "os_posix.h" + +#include "gk20a/gk20a.h" + +void nvgpu_wait_for_deferred_interrupts(struct gk20a *g) +{ + /* + * No interrupts in userspace so nothing to wait for. + */ +} + +int nvgpu_current_pid(struct gk20a *g) +{ + /* + * In the kernel this gets us the PID of the calling process for IOCTLs. + * But since we are in userspace this doesn't quite mean the same thing. + * This simply returns the PID of the currently running process. + */ + return (int)getpid(); +} + +int nvgpu_current_tid(struct gk20a *g) +{ + /* + * In POSIX thread ID is not the same as a process ID. In Linux threads + * and processes are represented by the same thing, but userspace can't + * really rely on that. + * + * We can, however, get a pthread_t for a given thread. But this + * pthread_t need not have any relation to the underlying system's + * representation of "threads". + */ + return (int)pthread_self(); +} + +void __nvgpu_print_current(struct gk20a *g, const char *func_name, int line, + void *ctx, enum nvgpu_log_type type) +{ + __nvgpu_log_msg(g, func_name, line, type, + "Current process: (nvgpu userspace)"); +} + +/* + * Somewhat meaningless in userspace... + */ +void nvgpu_kernel_restart(void *cmd) +{ + BUG(); +} + +/* + * We have no runtime PM stuff in userspace so these are really just noops. + */ +void gk20a_busy_noresume(struct gk20a *g) +{ +} + +void gk20a_idle_nosuspend(struct gk20a *g) +{ +} + +int gk20a_busy(struct gk20a *g) +{ + nvgpu_atomic_inc(&g->usage_count); + + return 0; +} + +void gk20a_idle(struct gk20a *g) +{ + nvgpu_atomic_dec(&g->usage_count); +} + +/* + * This function aims to initialize enough stuff to make unit testing worth + * while. There are several interfaces and APIs that rely on the struct gk20a's + * state in order to function: logging, for example, but there are many other + * things, too. + * + * Initialize as much of that as possible here. This is meant to be equivalent + * to the kernel space driver's probe function. + */ +struct gk20a *nvgpu_posix_probe(void) +{ + struct gk20a *g; + struct nvgpu_os_posix *p; + int err; + + p = malloc(sizeof(*p)); + if (p == NULL) + return NULL; + + g = &p->g; + + err = nvgpu_kmem_init(g); + if (err != 0) + goto fail; + + return g; + +fail: + free(p); + + return NULL; +} + +void nvgpu_posix_cleanup(struct gk20a *g) +{ + nvgpu_kmem_fini(g, 0); +} diff --git a/drivers/gpu/nvgpu/os/posix/nvlink.c b/drivers/gpu/nvgpu/os/posix/nvlink.c new file mode 100644 index 00000000..c830d6ed --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/nvlink.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +int nvgpu_nvlink_train(struct gk20a *g, u32 link_id, bool from_off) +{ + return -ENOSYS; +} + +int nvgpu_nvlink_enumerate(struct gk20a *g) +{ + return -ENOSYS; +} diff --git a/drivers/gpu/nvgpu/os/posix/os_posix.h b/drivers/gpu/nvgpu/os/posix/os_posix.h new file mode 100644 index 00000000..955186ef --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/os_posix.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __NVGPU_OS_POSIX_H__ +#define __NVGPU_OS_POSIX_H__ + +#include "gk20a/gk20a.h" + +struct nvgpu_os_posix { + struct gk20a g; +}; + +#endif diff --git a/drivers/gpu/nvgpu/os/posix/posix-comptags.c b/drivers/gpu/nvgpu/os/posix/posix-comptags.c new file mode 100644 index 00000000..a00246dd --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/posix-comptags.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include + +void gk20a_get_comptags(struct nvgpu_os_buffer *buf, + struct gk20a_comptags *comptags) +{ +} + +int gk20a_alloc_or_get_comptags(struct gk20a *g, + struct nvgpu_os_buffer *buf, + struct gk20a_comptag_allocator *allocator, + struct gk20a_comptags *comptags) +{ + return -ENODEV; +} + +bool gk20a_comptags_start_clear(struct nvgpu_os_buffer *buf) +{ + return false; +} + +void gk20a_comptags_finish_clear(struct nvgpu_os_buffer *buf, + bool clear_successful) +{ +} diff --git a/drivers/gpu/nvgpu/os/posix/posix-nvgpu_mem.c b/drivers/gpu/nvgpu/os/posix/posix-nvgpu_mem.c new file mode 100644 index 00000000..fa92a7c6 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/posix-nvgpu_mem.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +/* + * These functions are somewhat meaningless. + */ +u64 nvgpu_mem_get_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + return (u64)(uintptr_t)mem->cpu_va; +} + +u64 nvgpu_mem_get_phys_addr(struct gk20a *g, struct nvgpu_mem *mem) +{ + return (u64)(uintptr_t)mem->cpu_va; +} + +static struct nvgpu_sgl *nvgpu_mem_sgl_next(struct nvgpu_sgl *sgl) +{ + return NULL; +} + +static u64 nvgpu_mem_sgl_phys(struct gk20a *g, struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)(uintptr_t)mem->cpu_va; +} + +static u64 nvgpu_mem_sgl_dma(struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)(uintptr_t)mem->cpu_va; +} + +static u64 nvgpu_mem_sgl_length(struct nvgpu_sgl *sgl) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return (u64)mem->aligned_size; +} + +static u64 nvgpu_mem_sgl_gpu_addr(struct gk20a *g, struct nvgpu_sgl *sgl, + struct nvgpu_gmmu_attrs *attrs) +{ + struct nvgpu_mem *mem = (struct nvgpu_mem *)sgl; + + return mem->gpu_va; +} + +static bool nvgpu_mem_sgt_iommuable(struct gk20a *g, struct nvgpu_sgt *sgt) +{ + return nvgpu_iommuable(g); +} + +static void nvgpu_mem_sgt_free(struct gk20a *g, struct nvgpu_sgt *sgt) +{ + nvgpu_kfree(g, sgt); +} + +static struct nvgpu_sgt_ops nvgpu_sgt_posix_ops = { + .sgl_next = nvgpu_mem_sgl_next, + .sgl_phys = nvgpu_mem_sgl_phys, + .sgl_dma = nvgpu_mem_sgl_dma, + .sgl_length = nvgpu_mem_sgl_length, + .sgl_gpu_addr = nvgpu_mem_sgl_gpu_addr, + .sgt_iommuable = nvgpu_mem_sgt_iommuable, + .sgt_free = nvgpu_mem_sgt_free, +}; + +struct nvgpu_sgt *nvgpu_sgt_create_from_mem(struct gk20a *g, + struct nvgpu_mem *mem) +{ + struct nvgpu_sgt *sgt = nvgpu_kzalloc(g, sizeof(*sgt)); + + if (sgt == NULL) + return NULL; + + /* + * The userspace implementation is simple: a single 'entry' (which we + * only need the mem struct to describe). Maybe this could be expanded + * to be more interesting some day. + */ + sgt->sgl = (struct nvgpu_sgl *)mem; + sgt->ops = &nvgpu_sgt_posix_ops; + + return sgt; +} + +int nvgpu_mem_create_from_mem(struct gk20a *g, + struct nvgpu_mem *dest, struct nvgpu_mem *src, + int start_page, int nr_pages) +{ + u64 start = start_page * PAGE_SIZE; + u64 size = nr_pages * PAGE_SIZE; + + if (src->aperture != APERTURE_SYSMEM) + return -EINVAL; + + /* Some silly things a caller might do... */ + if (size > src->size) + return -EINVAL; + if ((start + size) > src->size) + return -EINVAL; + + memset(dest, 0, sizeof(*dest)); + + dest->cpu_va = ((char *)src->cpu_va) + start; + dest->mem_flags = src->mem_flags | NVGPU_MEM_FLAG_SHADOW_COPY; + dest->aperture = src->aperture; + dest->skip_wmb = src->skip_wmb; + dest->size = size; + + return 0; +} diff --git a/drivers/gpu/nvgpu/os/posix/posix-vm.c b/drivers/gpu/nvgpu/os/posix/posix-vm.c new file mode 100644 index 00000000..588b956d --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/posix-vm.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include + +#include + +u64 nvgpu_os_buf_get_size(struct nvgpu_os_buffer *os_buf) +{ + return os_buf->size; +} + +struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, + struct nvgpu_os_buffer *os_buf, + u64 map_addr, + u32 flags, + int kind) +{ + BUG(); + + /* + * No map caching for now. + */ + return NULL; +} + +void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer) +{ + free(mapped_buffer->os_priv.buf); +} diff --git a/drivers/gpu/nvgpu/os/posix/rwsem.c b/drivers/gpu/nvgpu/os/posix/rwsem.c new file mode 100644 index 00000000..7a696b75 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/rwsem.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include + +void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem) +{ + memset(rwsem, 0, sizeof(*rwsem)); + + nvgpu_spinlock_init(&rwsem->lock); +} + +/* + * Acquire. + */ +void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem) +{ + while (true) { + nvgpu_spinlock_acquire(&rwsem->lock); + + /* + * If there's a writer try again. + */ + if (rwsem->writers < 0) { + nvgpu_spinlock_release(&rwsem->lock); + nvgpu_msleep(10); + continue; + } + + /* + * Otherwise decrement the read counter and return. + */ + rwsem->readers -= 1; + nvgpu_spinlock_release(&rwsem->lock); + return; + } +} + +/* + * Release. + */ +void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem) +{ + nvgpu_spinlock_acquire(&rwsem->lock); + rwsem->readers += 1; + + /* + * Can't be any writers if there was a reader. Also can't be + * a positive number of readers. The increments are always + * downward so if we have a positive number then there is a + * balancing bug. + */ + BUG_ON(rwsem->writers < 0); + BUG_ON(rwsem->readers > 0); + + nvgpu_spinlock_release(&rwsem->lock); +} + +void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem) +{ + while (true) { + nvgpu_spinlock_acquire(&rwsem->lock); + + /* + * If there's a reader or a writer try again. Note: in this very + * simple implementation it's possible for readers to + * indefinitely starve writers. + */ + if (rwsem->writers < 0 || rwsem->readers < 0) { + nvgpu_spinlock_release(&rwsem->lock); + nvgpu_msleep(10); + continue; + } + + rwsem->writers -= 1; + nvgpu_spinlock_release(&rwsem->lock); + return; + } +} + +void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem) +{ + nvgpu_spinlock_acquire(&rwsem->lock); + rwsem->writers += 1; + + /* + * Writers can't be positive: that would be an unbalanced free. Readers + * must be zero - otherwise this writer should never have had access! + */ + BUG_ON(rwsem->writers > 0); + BUG_ON(rwsem->readers != 0); + + nvgpu_spinlock_release(&rwsem->lock); +} diff --git a/drivers/gpu/nvgpu/os/posix/soc.c b/drivers/gpu/nvgpu/os/posix/soc.c new file mode 100644 index 00000000..2346d61e --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/soc.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +bool nvgpu_platform_is_silicon(struct gk20a *g) +{ + return false; +} + +bool nvgpu_platform_is_simulation(struct gk20a *g) +{ + return false; +} + +bool nvgpu_platform_is_fpga(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_hypervisor_mode(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_bpmp_running(struct gk20a *g) +{ + return false; +} + +bool nvgpu_is_soc_t194_a01(struct gk20a *g) +{ + return false; +} diff --git a/drivers/gpu/nvgpu/os/posix/stubs.c b/drivers/gpu/nvgpu/os/posix/stubs.c new file mode 100644 index 00000000..1e50930a --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/stubs.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Here lie OS stubs that do not have an implementation yet nor has any plans + * for an implementation. + */ + +#include +#include + +#include "gk20a/dbg_gpu_gk20a.h" + +void nvgpu_dbg_session_post_event(struct dbg_session_gk20a *dbg_s) +{ +} + +int nvgpu_ecc_sysfs_init(struct gk20a *g) +{ + return 0; +} + +void nvgpu_ecc_sysfs_remove(struct gk20a *g) +{ +} + +int nvgpu_ltc_alloc_cbc(struct gk20a *g, size_t compbit_backing_size) +{ + return 0; +} diff --git a/drivers/gpu/nvgpu/os/posix/thread.c b/drivers/gpu/nvgpu/os/posix/thread.c new file mode 100644 index 00000000..d9476523 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/thread.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include + +/** + * Use pthreads to mostly emulate the Linux kernel APIs. There are some things + * that are quite different - especially the stop/should_stop notions. In user + * space threads can send signals to one another but of course within the kernel + * that is not as simple. + * + * This could use some nice debugging some day as well. + */ + +/* + * nvgpu thread functions return int. POSIX threads return void *. This little + * wrapper takes the int returning nvgpu thread and instead passes that int back + * through the void * pointer. + */ +static void *__nvgpu_posix_thread_wrapper(void *data) +{ + struct nvgpu_posix_thread_data *nvgpu = data; + + return ERR_PTR(nvgpu->fn(nvgpu->data)); +} + +int nvgpu_thread_create(struct nvgpu_thread *thread, + void *data, + int (*threadfn)(void *data), const char *name) +{ + int ret; + + BUG_ON(thread->running); + + memset(thread, 0, sizeof(*thread)); + + /* + * By subtracting 1 the above memset ensures that we have a zero + * terminated string. + */ + strncpy(thread->tname, name, NVGPU_THREAD_POSIX_MAX_NAMELEN - 1); + + thread->nvgpu.data = data; + thread->nvgpu.fn = threadfn; + + ret = pthread_create(&thread->thread, NULL, + __nvgpu_posix_thread_wrapper, + &thread->nvgpu); + if (ret != 0) + return ret; + +#ifdef _GNU_SOURCE + pthread_setname_np(thread->thread, thread->tname); +#endif + + thread->running = true; + + return 0; +} + +void nvgpu_thread_stop(struct nvgpu_thread *thread) +{ + thread->should_stop = true; +} + +bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) +{ + return thread->should_stop; +} + +bool nvgpu_thread_is_running(struct nvgpu_thread *thread) +{ + return thread->running; +} diff --git a/drivers/gpu/nvgpu/os/posix/timers.c b/drivers/gpu/nvgpu/os/posix/timers.c new file mode 100644 index 00000000..c84b0de5 --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/timers.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include + +#include +#include +#include + +static s64 now(void) +{ + return nvgpu_current_time_ms(); +} + +/* + * Returns true if a > b; + */ +static bool time_after(s64 a, s64 b) +{ + return a - b > 0; +} + +int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, + u32 duration, unsigned long flags) +{ + if (flags & ~NVGPU_TIMER_FLAG_MASK) + return -EINVAL; + + memset(timeout, 0, sizeof(*timeout)); + + timeout->g = g; + timeout->flags = flags; + + if (flags & NVGPU_TIMER_RETRY_TIMER) + timeout->retries.max = duration; + else + timeout->time = nvgpu_current_time_ms() + (s64)duration; + + return 0; +} + +static int __nvgpu_timeout_expired_msg_cpu(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + + if (time_after(now(), timeout->time)) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "Timeout detected @ %p %s", caller, buf); + } + + return -ETIMEDOUT; + } + + return 0; +} + +static int __nvgpu_timeout_expired_msg_retry(struct nvgpu_timeout *timeout, + void *caller, + const char *fmt, va_list args) +{ + struct gk20a *g = timeout->g; + + if (timeout->retries.attempted >= timeout->retries.max) { + if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + char buf[128]; + + vsnprintf(buf, sizeof(buf), fmt, args); + + nvgpu_err(g, "No more retries @ %p %s", caller, buf); + } + + return -ETIMEDOUT; + } + + timeout->retries.attempted++; + + return 0; +} + +int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout, + void *caller, const char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + ret = __nvgpu_timeout_expired_msg_retry(timeout, caller, fmt, + args); + else + ret = __nvgpu_timeout_expired_msg_cpu(timeout, caller, fmt, + args); + va_end(args); + + return ret; +} + +int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout) +{ + if (timeout->flags & NVGPU_TIMER_RETRY_TIMER) + return timeout->retries.attempted >= timeout->retries.max; + else + return time_after(now(), timeout->time); +} + +void nvgpu_udelay(unsigned int usecs) +{ + BUG(); +} + +void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us) +{ + BUG(); +} + +void nvgpu_msleep(unsigned int msecs) +{ + BUG(); +} + +static inline s64 __nvgpu_current_time_us(void) +{ + struct timeval now; + s64 time_now; + int ret; + + ret = gettimeofday(&now, NULL); + if (ret != 0) + BUG(); + + time_now = ((s64)now.tv_sec * (s64)1000000) + (s64)now.tv_usec; + + return time_now; +} + +s64 nvgpu_current_time_ms(void) +{ + return __nvgpu_current_time_us() / (s64)1000; +} + +u64 nvgpu_hr_timestamp(void) +{ + return __nvgpu_current_time_us(); +} diff --git a/drivers/gpu/nvgpu/os/posix/tsg.c b/drivers/gpu/nvgpu/os/posix/tsg.c new file mode 100644 index 00000000..8736123d --- /dev/null +++ b/drivers/gpu/nvgpu/os/posix/tsg.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "gk20a/tsg_gk20a.h" + +void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg, + int __event_id) +{ +} -- cgit v1.2.2