summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libddekit/resources.c76
1 files changed, 63 insertions, 13 deletions
diff --git a/libddekit/resources.c b/libddekit/resources.c
index 4bbd2db9..8303af15 100644
--- a/libddekit/resources.c
+++ b/libddekit/resources.c
@@ -1,4 +1,8 @@
+#include <error.h>
#include <sys/io.h>
+#include <mach.h>
+#include <hurd.h>
+#include <device/device.h>
#include "ddekit/resources.h"
@@ -36,6 +40,36 @@ int ddekit_release_io(ddekit_addr_t start, ddekit_addr_t count) {
return ioperm (start, count, 0);
}
+/* Get a memory object for the whole physical address space. */
+static memory_object_t get_physmem_object(void)
+{
+ mach_port_t master_device_port;
+ mach_port_t iopl_dev;
+ memory_object_t obj;
+ kern_return_t err;
+
+ /* first open master device port */
+ err = get_privileged_ports(NULL, &master_device_port);
+ if (err)
+ error(2, err, "get_physmem_object() can't get master device port");
+
+ /* now use it to open iopl device */
+ err = device_open(master_device_port, VM_PROT_READ | VM_PROT_WRITE, "iopl", &iopl_dev);
+ if (err)
+ error(2, err, "get_physmem_object() can't open iopl device");
+
+ mach_port_deallocate(mach_task_self(), master_device_port);
+
+ /* now use that to get a memory object for the physical address space */
+ err = device_map(iopl_dev, D_READ|D_WRITE, 0, ~0, &obj, 0);
+ if (err)
+ error(2, err, "get_physmem_object() can't obtain memory object");
+
+ mach_port_deallocate(mach_task_self(), iopl_dev);
+
+ return obj;
+}
+
/** Request a memory region.
*
* \return vaddr virtual address of memory region
@@ -43,17 +77,30 @@ int ddekit_release_io(ddekit_addr_t start, ddekit_addr_t count) {
* \return -1 error
*/
int ddekit_request_mem(ddekit_addr_t start, ddekit_addr_t count, ddekit_addr_t *vaddr) {
-#if 0
- ddekit_addr_t v;
+ memory_object_t iopl_mem;
+ kern_return_t err;
+ *vaddr = 0;
+
+ iopl_mem = get_physmem_object();
- v = l4io_request_mem_region(start, count, 0);
- if (v) {
- *vaddr = v;
- return 0;
- } else
+ err = vm_map(mach_task_self(),
+ (vm_address_t *) vaddr,
+ count,
+ 0, /* mask */
+ 1, /* anywhere */
+ iopl_mem,
+ (vm_offset_t)start,
+ 0, /* copy on write */
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_PROT_READ|VM_PROT_WRITE,
+ VM_INHERIT_SHARE);
+ mach_port_deallocate(mach_task_self(),iopl_mem);
+ if( err )
+ {
+ error(0, err, "mmio_map(): can't vm_map");
return -1;
-#endif
- return -1;
+ }
+ return 0;
}
/** Release memory region.
@@ -62,8 +109,11 @@ int ddekit_request_mem(ddekit_addr_t start, ddekit_addr_t count, ddekit_addr_t *
* \return <0 error
*/
int ddekit_release_mem(ddekit_addr_t start, ddekit_addr_t count) {
-#if 0
- return l4io_release_mem_region(start, count);
-#endif
- return -1;
+ kern_return_t err = vm_deallocate(mach_task_self(), start, count);
+ if( err )
+ {
+ error(0, err, "mmio_unmap(): can't dealloc mmio space");
+ return -1;
+ }
+ return 0;
}