summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-03-04 21:19:15 +0000
committerkettenis <kettenis@openbsd.org>2020-03-04 21:19:15 +0000
commitec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e (patch)
tree26aca4c5a8544552e1366b97455405701a3dd5ab
parentDo not count pages mapped as PROT_NONE against the RLIMIT_DATA limit. (diff)
downloadwireguard-openbsd-ec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e.tar.xz
wireguard-openbsd-ec0f107b4209bc9fc8f61f5b22f9212aa8da7b8e.zip
Properly implement the page fault handler for CMA GEM buffers and actually
make drm(4) attach to rkdrm(4). This makes KMS work on the RK3399 SoC. ok patrick@
-rw-r--r--sys/dev/fdt/rkdrm.c29
-rw-r--r--sys/dev/pci/drm/drm_drv.c4
-rw-r--r--sys/dev/pci/drm/drm_gem_cma_helper.c53
-rw-r--r--sys/dev/pci/drm/include/drm/drmP.h4
-rw-r--r--sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h3
5 files changed, 45 insertions, 48 deletions
diff --git a/sys/dev/fdt/rkdrm.c b/sys/dev/fdt/rkdrm.c
index ec8c1b1c678..ac12a48661b 100644
--- a/sys/dev/fdt/rkdrm.c
+++ b/sys/dev/fdt/rkdrm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkdrm.c,v 1.1 2020/02/21 15:44:54 patrick Exp $ */
+/* $OpenBSD: rkdrm.c,v 1.2 2020/03/04 21:19:15 kettenis Exp $ */
/* $NetBSD: rk_drm.c,v 1.3 2019/12/15 01:00:58 mrg Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca>
@@ -72,8 +72,11 @@ void rkdrm_disable_vblank(struct drm_device *, unsigned int);
int rkdrm_load(struct drm_device *, unsigned long);
int rkdrm_unload(struct drm_device *);
+int rkdrm_gem_fault(struct drm_gem_object *, struct uvm_faultinfo *,
+ off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int);
+
struct drm_driver rkdrm_driver = {
- .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
+ .driver_features = DRIVER_MODESET | DRIVER_GEM,
.get_vblank_counter = rkdrm_get_vblank_counter,
.enable_vblank = rkdrm_enable_vblank,
@@ -82,7 +85,8 @@ struct drm_driver rkdrm_driver = {
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
- /* XXX GEM stuff */
+ .gem_free_object_unlocked = drm_gem_cma_free_object,
+ .gem_fault = drm_gem_cma_fault,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
@@ -113,6 +117,7 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux)
{
struct rkdrm_softc *sc = (struct rkdrm_softc *)self;
struct fdt_attach_args *faa = aux;
+ struct drm_attach_args arg;
sc->sc_dmat = faa->fa_dmat;
sc->sc_iot = faa->fa_iot;
@@ -120,6 +125,15 @@ rkdrm_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
+ memset(&arg, 0, sizeof(arg));
+ arg.driver = &rkdrm_driver;
+ arg.drm = &sc->sc_ddev;
+ arg.dmat = faa->fa_dmat;
+ arg.bst = faa->fa_iot;
+ arg.busid = sc->sc_dev.dv_xname;
+ arg.busid_len = strlen(sc->sc_dev.dv_xname) + 1;
+ config_found_sm(self, &arg, drmprint, drmsubmatch);
+
config_mountroot(self, rkdrm_attachhook);
}
@@ -299,7 +313,7 @@ rkdrm_wsioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
switch (cmd) {
case WSDISPLAYIO_GTYPE:
- *(u_int *)data = WSDISPLAY_TYPE_EFIFB;
+ *(u_int *)data = WSDISPLAY_TYPE_RKDRM;
return 0;
case WSDISPLAYIO_GINFO:
wdf = (struct wsdisplay_fbinfo *)data;
@@ -416,11 +430,6 @@ rkdrm_attachhook(struct device *dev)
return;
}
- sc->sc_ddev.driver = &rkdrm_driver;
- sc->sc_ddev.dev_private = sc;
- sc->sc_ddev.bst = sc->sc_iot;
- sc->sc_ddev.dmat = sc->sc_dmat;
-
drm_mode_config_init(&sc->sc_ddev);
sc->sc_ddev.mode_config.min_width = 0;
sc->sc_ddev.mode_config.min_height = 0;
@@ -495,9 +504,7 @@ rkdrm_attachhook(struct device *dev)
config_found_sm(&sc->sc_dev, &aa, wsemuldisplaydevprint,
wsemuldisplaydevsubmatch);
-#ifdef notyet
drm_dev_register(&sc->sc_ddev, 0);
-#endif
}
int
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index c5969e94e05..d34e7f4bef2 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_drv.c,v 1.172 2020/03/03 09:23:54 kettenis Exp $ */
+/* $OpenBSD: drm_drv.c,v 1.173 2020/03/04 21:19:15 kettenis Exp $ */
/*-
* Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org>
* Copyright © 2008 Intel Corporation
@@ -87,8 +87,6 @@ int drm_detach(struct device *, int);
void drm_quiesce(struct drm_device *);
void drm_wakeup(struct drm_device *);
int drm_activate(struct device *, int);
-int drmprint(void *, const char *);
-int drmsubmatch(struct device *, void *, void *);
int drm_dequeue_event(struct drm_device *, struct drm_file *, size_t,
struct drm_pending_event **);
diff --git a/sys/dev/pci/drm/drm_gem_cma_helper.c b/sys/dev/pci/drm/drm_gem_cma_helper.c
index 30bf992d263..8e0021c4ab7 100644
--- a/sys/dev/pci/drm/drm_gem_cma_helper.c
+++ b/sys/dev/pci/drm/drm_gem_cma_helper.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_gem_cma_helper.c,v 1.1 2020/02/21 15:42:36 patrick Exp $ */
+/* $OpenBSD: drm_gem_cma_helper.c,v 1.2 2020/03/04 21:19:15 kettenis Exp $ */
/* $NetBSD: drm_gem_cma_helper.c,v 1.9 2019/11/05 23:29:28 jmcneill Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill@invisible.ca>
@@ -76,10 +76,14 @@ drm_gem_cma_create_internal(struct drm_device *ddev, size_t size,
#endif
memset(obj->vaddr, 0, obj->dmasize);
- drm_gem_private_object_init(ddev, &obj->base, size);
+ error = drm_gem_object_init(ddev, &obj->base, size);
+ if (error)
+ goto unload;
return obj;
+unload:
+ bus_dmamap_unload(obj->dmat, obj->dmamap);
destroy:
bus_dmamap_destroy(obj->dmat, obj->dmamap);
unmap:
@@ -189,51 +193,44 @@ done:
return error;
}
-static int
-drm_gem_cma_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr,
- struct vm_page **pps, int npages, int centeridx, vm_prot_t access_type,
- int flags)
+int
+drm_gem_cma_fault(struct drm_gem_object *gem_obj, struct uvm_faultinfo *ufi,
+ off_t offset, vaddr_t vaddr, vm_page_t *pps, int npages, int centeridx,
+ vm_prot_t access_type, int flags)
{
struct vm_map_entry *entry = ufi->entry;
- struct uvm_object *uobj = entry->object.uvm_obj;
- struct drm_gem_object *gem_obj =
- container_of(uobj, struct drm_gem_object, uobj);
struct drm_gem_cma_object *obj = to_drm_gem_cma_obj(gem_obj);
- off_t curr_offset;
- vaddr_t curr_va;
+ struct uvm_object *uobj = &obj->base.uobj;
paddr_t paddr;
int lcv, retval;
vm_prot_t mapprot;
- if (UVM_ET_ISCOPYONWRITE(entry))
- return EIO;
-
- curr_offset = entry->offset + (vaddr - entry->start);
- curr_va = vaddr;
+ offset -= drm_vma_node_offset_addr(&obj->base.vma_node);
+ mapprot = ufi->entry->protection;
retval = 0;
- for (lcv = 0; lcv < npages; lcv++, curr_offset += PAGE_SIZE,
- curr_va += PAGE_SIZE) {
+ for (lcv = 0; lcv < npages; lcv++, offset += PAGE_SIZE,
+ vaddr += PAGE_SIZE) {
if ((flags & PGO_ALLPAGES) == 0 && lcv != centeridx)
continue;
+
if (pps[lcv] == PGO_DONTCARE)
continue;
paddr = bus_dmamem_mmap(obj->dmat, obj->dmasegs, 1,
- curr_offset, access_type, 0);
+ offset, access_type, BUS_DMA_NOCACHE);
if (paddr == -1) {
- retval = EIO;
+ retval = VM_PAGER_BAD;
break;
}
- mapprot = ufi->entry->protection;
- if (pmap_enter(ufi->orig_map->pmap, curr_va, paddr, mapprot,
- PMAP_CANFAIL | mapprot) != 0) {
+ if (pmap_enter(ufi->orig_map->pmap, vaddr, paddr,
+ mapprot, PMAP_CANFAIL | mapprot) != 0) {
pmap_update(ufi->orig_map->pmap);
uvmfault_unlockall(ufi, ufi->entry->aref.ar_amap,
uobj, NULL);
uvm_wait("drm_gem_cma_fault");
- return ERESTART;
+ return VM_PAGER_REFAULT;
}
}
@@ -243,14 +240,6 @@ drm_gem_cma_fault(struct uvm_faultinfo *ufi, vaddr_t vaddr,
return retval;
}
-#ifdef notyet
-const struct uvm_pagerops drm_gem_cma_uvm_ops = {
- .pgo_reference = drm_gem_pager_reference,
- .pgo_detach = drm_gem_pager_detach,
- .pgo_fault = drm_gem_cma_fault,
-};
-#endif
-
struct sg_table *
drm_gem_cma_prime_get_sg_table(struct drm_gem_object *gem_obj)
{
diff --git a/sys/dev/pci/drm/include/drm/drmP.h b/sys/dev/pci/drm/include/drm/drmP.h
index 041c14c797a..832d016032b 100644
--- a/sys/dev/pci/drm/include/drm/drmP.h
+++ b/sys/dev/pci/drm/include/drm/drmP.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: drmP.h,v 1.7 2020/03/03 09:23:54 kettenis Exp $ */
+/* $OpenBSD: drmP.h,v 1.8 2020/03/04 21:19:15 kettenis Exp $ */
/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
*/
@@ -239,6 +239,8 @@ int drm_linux_acpi_notify(struct aml_node *, int, void *);
int drm_pciprobe(struct pci_attach_args *, const struct drm_pcidev * );
struct drm_device *drm_attach_pci(struct drm_driver *,
struct pci_attach_args *, int, int, struct device *, struct drm_device *);
+int drmprint(void *, const char *);
+int drmsubmatch(struct device *, void *, void *);
dev_type_ioctl(drmioctl);
dev_type_read(drmread);
dev_type_poll(drmpoll);
diff --git a/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h b/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h
index df4e4de031a..b388a0d99c7 100644
--- a/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h
+++ b/sys/dev/pci/drm/include/drm/drm_gem_cma_helper.h
@@ -11,7 +11,8 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *, struct drm_device *,
struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *,
size_t);
-extern const struct uvm_pagerops drm_gem_cma_uvm_ops;
+int drm_gem_cma_fault(struct drm_gem_object *, struct uvm_faultinfo *,
+ off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int);
struct drm_gem_cma_object {
struct drm_gem_object base;