>From d487e6393191f29361f76fcb89ea02f561fea82a Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Sun, 5 Jul 2020 16:42:28 +1000 Subject: [PATCH] Add ds_device_vm_allocate_contiguous RPC --- device/ds_routines.c | 17 +++++++++++++++++ include/device/device.defs | 31 +++++++++++++++++++++++++++++++ include/mach/mach.defs | 33 +-------------------------------- vm/vm_user.c | 6 +----- vm/vm_user.h | 2 ++ 5 files changed, 52 insertions(+), 37 deletions(-) diff --git a/device/ds_routines.c b/device/ds_routines.c index 69e963bd..28100da1 100644 --- a/device/ds_routines.c +++ b/device/ds_routines.c @@ -1848,6 +1848,23 @@ ds_device_intr_ack (device_t dev, ipc_port_t receive_port) return irq_acknowledge(receive_port); } +kern_return_t +ds_device_allocate_contiguous (device_t dev, vm_address_t *vaddr, + vm_address_t *paddr, vm_size_t size) +{ + mach_device_t mdev = dev->emul_data; + + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + /* Must be called on the mem device only */ + if (! name_equal(mdev->dev_ops->d_name, 3, "mem")) + return D_INVALID_OPERATION; + + return vm_allocate_contiguous (kernel_map, vaddr, paddr, size); +} + struct device_emulation_ops mach_device_emulation_ops = { (void*) mach_device_reference, diff --git a/include/device/device.defs b/include/device/device.defs index ec4b5bf8..bf81b9ae 100644 --- a/include/device/device.defs +++ b/include/device/device.defs @@ -160,3 +160,34 @@ routine device_intr_ack( device : device_t; in receive_port : mach_port_send_t); +/* + * This routine is created for allocating DMA buffers. + * We are going to get contiguous physical memory + * and its physical address in addition to the virtual address. + * It only works on the mem device. + */ + /* XXX + This RPC lacks a few additional constraints like boundaries, alignment +and maybe phase. We may not use them now, but they're important for +portability (e.g. if GNU Mach supports PAE, drivers that can't use +physical memory beyond the 4 GiB limit must be able to express it). + +> What do you mean by "phase"? + +Offset from the alignment. But I don't think it's useful at all in this +case. Minimum and maximum addresses and alignment should do. Maybe +boundary crossing but usually, specifying the right alignment and size +is enough. + +For upstream +inclusion, we need to do it properly: the RPC should return a special +memory object (similar to device_map() ), which can then be mapped into +the process address space with vm_map() like any other memory object. + +phys_address_t? + */ +routine device_allocate_contiguous( + device : device_t; + out vaddr : vm_address_t; + out paddr : vm_address_t; + size : vm_size_t); diff --git a/include/mach/mach.defs b/include/mach/mach.defs index 77cc7d49..20f425fa 100644 --- a/include/mach/mach.defs +++ b/include/mach/mach.defs @@ -719,38 +719,7 @@ skip; /* old host_fpa_counters_reset */ #endif /* ! KERNEL_USER */ -/* - * This routine is created for allocating DMA buffers. - * We are going to get a contiguous physical memory - * and its physical address in addition to the virtual address. - */ - - /* XXX - This RPC lacks a few additional constraints like boundaries, alignment -and maybe phase. We may not use them now, but they're important for -portability (e.g. if GNU Mach supports PAE, drivers that can't use -physical memory beyond the 4 GiB limit must be able to express it). - -> What do you mean by "phase"? - -Offset from the alignment. But I don't think it's useful at all in this -case. Minimum and maximum addresses and alignment should do. Maybe -boundary crossing but usually, specifying the right alignment and size -is enough. - -For upstream -inclusion, we need to do it properly: the RPC should return a special -memory object (similar to device_map() ), which can then be mapped into -the process address space with vm_map() like any other memory object. - -phys_address_t? - */ -routine vm_allocate_contiguous( - host_priv : host_priv_t; - target_task : vm_task_t; - out vaddr : vm_address_t; - out paddr : vm_address_t; - size : vm_size_t); +skip; /* old vm_allocate_contiguous */ /* * There is no more room in this interface for additional calls. diff --git a/vm/vm_user.c b/vm/vm_user.c index 1789dbfa..44a3e578 100644 --- a/vm/vm_user.c +++ b/vm/vm_user.c @@ -532,8 +532,7 @@ kern_return_t vm_msync( return vm_map_msync(map, (vm_offset_t) address, size, sync_flags); } -kern_return_t vm_allocate_contiguous(host_priv, map, result_vaddr, result_paddr, size) - host_t host_priv; +kern_return_t vm_allocate_contiguous(map, result_vaddr, result_paddr, size) vm_map_t map; vm_address_t *result_vaddr; vm_address_t *result_paddr; @@ -548,9 +547,6 @@ kern_return_t vm_allocate_contiguous(host_priv, map, result_vaddr, result_paddr, kern_return_t kr; vm_address_t vaddr; - if (host_priv == HOST_NULL) - return KERN_INVALID_HOST; - if (map == VM_MAP_NULL) return KERN_INVALID_TASK; diff --git a/vm/vm_user.h b/vm/vm_user.h index c6f20a82..85918417 100644 --- a/vm/vm_user.h +++ b/vm/vm_user.h @@ -56,5 +56,7 @@ extern kern_return_t vm_copy(vm_map_t, vm_address_t, vm_size_t, extern kern_return_t vm_map(vm_map_t, vm_offset_t *, vm_size_t, vm_offset_t, boolean_t, ipc_port_t, vm_offset_t, boolean_t, vm_prot_t, vm_prot_t, vm_inherit_t); +extern kern_return_t vm_allocate_contiguous(vm_map_t, vm_address_t *, + vm_address_t *, vm_size_t); #endif /* _VM_VM_USER_H_ */ -- 2.25.1