1/* $NetBSD: nouveau_nvkm_subdev_fault_user.c,v 1.3 2021/12/19 10:51:58 riastradh Exp $ */ 2 3/* 4 * Copyright 2018 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24#include <sys/cdefs.h> 25__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_fault_user.c,v 1.3 2021/12/19 10:51:58 riastradh Exp $"); 26 27#include "priv.h" 28 29#include <core/memory.h> 30#include <subdev/mmu.h> 31 32#include <nvif/clb069.h> 33#include <nvif/unpack.h> 34 35static int 36#ifdef __NetBSD__ 37nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, 38 enum nvkm_object_map *type, 39 bus_space_tag_t *tag, u64 *addr, u64 *size) 40#else 41nvkm_ufault_map(struct nvkm_object *object, void *argv, u32 argc, 42 enum nvkm_object_map *type, u64 *addr, u64 *size) 43#endif 44{ 45 struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); 46 struct nvkm_device *device = buffer->fault->subdev.device; 47 *type = NVKM_OBJECT_MAP_IO; 48#ifdef __NetBSD__ 49 *tag = device->func->resource_tag(device, 3); 50#endif 51 *addr = device->func->resource_addr(device, 3) + buffer->addr; 52 *size = nvkm_memory_size(buffer->mem); 53 return 0; 54} 55 56static int 57nvkm_ufault_ntfy(struct nvkm_object *object, u32 type, 58 struct nvkm_event **pevent) 59{ 60 struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); 61 if (type == NVB069_V0_NTFY_FAULT) { 62 *pevent = &buffer->fault->event; 63 return 0; 64 } 65 return -EINVAL; 66} 67 68static int 69nvkm_ufault_fini(struct nvkm_object *object, bool suspend) 70{ 71 struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); 72 buffer->fault->func->buffer.fini(buffer); 73 return 0; 74} 75 76static int 77nvkm_ufault_init(struct nvkm_object *object) 78{ 79 struct nvkm_fault_buffer *buffer = nvkm_fault_buffer(object); 80 buffer->fault->func->buffer.init(buffer); 81 return 0; 82} 83 84static void * 85nvkm_ufault_dtor(struct nvkm_object *object) 86{ 87 return NULL; 88} 89 90static const struct nvkm_object_func 91nvkm_ufault = { 92 .dtor = nvkm_ufault_dtor, 93 .init = nvkm_ufault_init, 94 .fini = nvkm_ufault_fini, 95 .ntfy = nvkm_ufault_ntfy, 96 .map = nvkm_ufault_map, 97}; 98 99int 100nvkm_ufault_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, 101 void *argv, u32 argc, struct nvkm_object **pobject) 102{ 103 union { 104 struct nvif_clb069_v0 v0; 105 } *args = argv; 106 struct nvkm_fault *fault = device->fault; 107 struct nvkm_fault_buffer *buffer = fault->buffer[fault->func->user.rp]; 108 int ret = -ENOSYS; 109 110 if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { 111 args->v0.entries = buffer->entries; 112 args->v0.get = buffer->get; 113 args->v0.put = buffer->put; 114 } else 115 return ret; 116 117 nvkm_object_ctor(&nvkm_ufault, oclass, &buffer->object); 118 *pobject = &buffer->object; 119 return 0; 120} 121