diff options
author | Justus Winter <justus@gnupg.org> | 2016-04-15 11:49:03 +0200 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-04-15 11:49:03 +0200 |
commit | e337dc65191ade95f164b1c4abea5d5826344c54 (patch) | |
tree | 375121cae6f45158d0fec75cff04481e63c96469 /debian/patches | |
parent | 1a55942b67f190f9919e142c72b0d3051231bfb8 (diff) |
drop old patch series
Diffstat (limited to 'debian/patches')
-rw-r--r-- | debian/patches/700002-70_new_dde.patch.patch | 1001 | ||||
-rw-r--r-- | debian/patches/series | 1 |
2 files changed, 0 insertions, 1002 deletions
diff --git a/debian/patches/700002-70_new_dde.patch.patch b/debian/patches/700002-70_new_dde.patch.patch deleted file mode 100644 index e5d6b97..0000000 --- a/debian/patches/700002-70_new_dde.patch.patch +++ /dev/null @@ -1,1001 +0,0 @@ -From 168b41b26ae8b2730719a43cf71650b13d7b0c2c Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Thu, 25 Feb 2016 18:46:32 +0100 -Subject: [PATCH gnumach 2/2] 70_new_dde.patch - ---- - Makefrag.am | 9 ++ - device/ds_routines.c | 27 ++++ - device/interrupt.h | 34 ++++ - device/intr.c | 341 +++++++++++++++++++++++++++++++++++++++ - include/device/intr.h | 18 +++ - include/mach/experimental.defs | 98 +++++++++++ - kern/experimental.srv | 3 + - kern/ipc_kobject.c | 11 ++ - kern/ipc_kobject.h | 5 +- - kern/startup.c | 4 + - linux/dev/arch/i386/kernel/irq.c | 66 +++++++- - linux/dev/drivers/block/genhd.c | 4 +- - vm/vm_user.c | 103 ++++++++++++ - 13 files changed, 719 insertions(+), 4 deletions(-) - create mode 100644 device/interrupt.h - create mode 100644 device/intr.c - create mode 100644 include/device/intr.h - create mode 100644 include/mach/experimental.defs - create mode 100644 kern/experimental.srv - -diff --git a/Makefrag.am b/Makefrag.am -index 9a68af8..de11a71 100644 ---- a/Makefrag.am -+++ b/Makefrag.am -@@ -220,6 +220,7 @@ EXTRA_DIST += \ - kern/mach.srv \ - kern/mach4.srv \ - kern/gnumach.srv \ -+ kern/experimental.srv \ - kern/mach_debug.srv \ - kern/mach_host.srv \ - kern/task_notify.cli -@@ -304,6 +305,7 @@ libkernel_a_SOURCES += \ - device/device_types_kernel.h \ - device/ds_routines.c \ - device/ds_routines.h \ -+ device/intr.c \ - device/if_ether.h \ - device/if_hdr.h \ - device/io_req.h \ -@@ -352,6 +354,7 @@ include_device_HEADERS = \ - include/device/device_types.defs \ - include/device/device_types.h \ - include/device/disk_status.h \ -+ include/device/intr.h \ - include/device/net_status.h \ - include/device/tape_status.h \ - include/device/tty_status.h -@@ -374,6 +377,7 @@ include_mach_HEADERS = \ - include/mach/memory_object_default.defs \ - include/mach/notify.defs \ - include/mach/std_types.defs \ -+ include/mach/experimental.defs \ - include/mach/alert.h \ - include/mach/boolean.h \ - include/mach/boot.h \ -@@ -522,6 +526,7 @@ nodist_lib_dep_tr_for_defs_a_SOURCES += \ - kern/mach.server.defs.c \ - kern/mach4.server.defs.c \ - kern/gnumach.server.defs.c \ -+ kern/experimental.server.defs.c \ - kern/mach_debug.server.defs.c \ - kern/mach_host.server.defs.c - nodist_libkernel_a_SOURCES += \ -@@ -534,6 +539,9 @@ nodist_libkernel_a_SOURCES += \ - kern/gnumach.server.h \ - kern/gnumach.server.c \ - kern/gnumach.server.msgids \ -+ kern/experimental.server.h \ -+ kern/experimental.server.c \ -+ kern/experimental.server.msgids \ - kern/mach_debug.server.h \ - kern/mach_debug.server.c \ - kern/mach_debug.server.msgids \ -@@ -543,6 +551,7 @@ nodist_libkernel_a_SOURCES += \ - # kern/mach.server.defs - # kern/mach4.server.defs - # kern/gnumach.server.defs -+# kern/experimental.server.defs - # kern/mach_debug.server.defs - # kern/mach_host.server.defs - -diff --git a/device/ds_routines.c b/device/ds_routines.c -index dbff7f8..ec26044 100644 ---- a/device/ds_routines.c -+++ b/device/ds_routines.c -@@ -87,6 +87,7 @@ - #include <device/dev_hdr.h> - #include <device/conf.h> - #include <device/io_req.h> -+#include <device/interrupt.h> - #include <device/ds_routines.h> - #include <device/net_status.h> - #include <device/device_port.h> -@@ -318,6 +319,26 @@ ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset, - offset, size, pager, unmap); - } - -+io_return_t -+experimental_device_intr_register (ipc_port_t master_port, int line, -+ int id, int flags, ipc_port_t receive_port) -+{ -+#ifdef MACH_XEN -+ return D_INVALID_OPERATION; -+#else /* MACH_XEN */ -+ io_return_t ret; -+ -+ /* Open must be called on the master device port. */ -+ if (master_port != master_device_port) -+ return D_INVALID_OPERATION; -+ -+ if (receive_port == IP_NULL) -+ return D_INVALID_OPERATION; -+ -+ return insert_intr_entry (line, receive_port); -+#endif /* MACH_XEN */ -+} -+ - boolean_t - ds_notify (mach_msg_header_t *msg) - { -@@ -1798,6 +1819,12 @@ device_writev_trap (mach_device_t device, dev_mode_t mode, - return (result); - } - -+kern_return_t -+experimental_device_intr_enable(ipc_port_t master_port, int line, char status) -+{ -+ return D_INVALID_OPERATION; -+} -+ - struct device_emulation_ops mach_device_emulation_ops = - { - (void*) mach_device_reference, -diff --git a/device/interrupt.h b/device/interrupt.h -new file mode 100644 -index 0000000..855f163 ---- /dev/null -+++ b/device/interrupt.h -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (c) 2016 Free Software Foundation. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef DEVICE_INTERRUPT_H -+#define DEVICE_INTERRUPT_H -+ -+struct intr_entry; -+boolean_t queue_intr (struct intr_entry *e); -+kern_return_t insert_intr_entry (int line, ipc_port_t notification_port); -+ -+boolean_t intr_entry_notify (mach_msg_header_t *msg); -+void intr_thread (void); -+ -+/* linux/dev/arch/i386/kernel/irq.c */ -+int install_user_intr_handler (unsigned int line, -+ unsigned long flags, -+ struct intr_entry *entry); -+int remove_user_intr_handler (unsigned int irq, struct intr_entry *entry); -+ -+#endif /* DEVICE_INTERRUPT_H */ -diff --git a/device/intr.c b/device/intr.c -new file mode 100644 -index 0000000..85915cd ---- /dev/null -+++ b/device/intr.c -@@ -0,0 +1,341 @@ -+/* -+ * Copyright (c) 2010-2016 Free Software Foundation. -+ * -+ * This program is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <device/intr.h> -+#include <device/ds_routines.h> -+#include <ipc/ipc_space.h> -+#include <kern/debug.h> -+#include <kern/queue.h> -+#include <kern/printf.h> -+#include <mach/notify.h> -+#include <machine/cpu.h> -+ -+#include "interrupt.h" -+ -+#ifndef MACH_XEN -+ -+/* The cache which holds our proxy memory objects. */ -+static struct kmem_cache intr_entry_cache; -+ -+struct intr_entry -+{ -+ ipc_port_t port; /* We receive notifications on this port. */ -+ queue_chain_t chain; -+ ipc_port_t notification_port; -+ int line; -+ /* The number of interrupts occur since last run of intr_thread. */ -+ int interrupts; -+}; -+typedef struct intr_entry *intr_entry_t; -+ -+static queue_head_t intr_queue; -+ -+/* This function can only be used in the interrupt handler. */ -+boolean_t -+queue_intr (struct intr_entry *e) -+{ -+ unsigned long flags; -+ -+ cpu_intr_save (&flags); -+ e->interrupts++; -+ cpu_intr_restore (flags); -+ -+ thread_wakeup ((event_t) &intr_thread); -+ return TRUE; -+} -+ -+/* insert an interrupt entry in the queue. -+ * This entry exists in the queue until -+ * the corresponding interrupt port is removed.*/ -+kern_return_t -+insert_intr_entry (int line, ipc_port_t notification_port) -+{ -+ kern_return_t err = 0; -+ unsigned long flags; -+ struct intr_entry *e, *new; -+ int free = 0; -+ ipc_port_t dnnotify; -+ ipc_port_request_index_t dnindex; -+ -+ /* XXX: move to arch-specific */ -+ if (line < 0 || line >= 16) -+ return D_INVALID_OPERATION; -+ -+ new = (struct intr_entry *) kmem_cache_alloc (&intr_entry_cache); -+ if (new == NULL) -+ return D_NO_MEMORY; -+ -+ /* Allocate port, keeping a reference for it. */ -+ new->port = ipc_port_alloc_kernel (); -+ if (new->port == IP_NULL) -+ { -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ return KERN_RESOURCE_SHORTAGE; -+ } -+ -+ /* Associate the port with the object. */ -+ ipc_kobject_set (new->port, (ipc_kobject_t) new, IKOT_INTR_ENTRY); -+ -+ new->line = line; -+ new->notification_port = notification_port; -+ new->interrupts = 0; -+ -+ /* Register a dead-name notification so that we are notified if the -+ userspace handler dies. */ -+ dnnotify = ipc_port_make_sonce (new->port); -+ ip_lock (notification_port); -+ /* We use a bogus port name. We don't need it to distinguish the -+ notifications because we register just one per object. */ -+ retry: -+ err = ipc_port_dnrequest (notification_port, (mach_port_t) 1, dnnotify, &dnindex); -+ if (err) -+ { -+ err = ipc_port_dngrow (notification_port); -+ /* notification_port is unlocked */ -+ if (err != KERN_SUCCESS) -+ { -+ ipc_port_release_sonce (dnnotify); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ return err; -+ } -+ ip_lock (notification_port); -+ goto retry; -+ } -+ /* notification_port is locked. dnindex is only valid until we unlock it and we -+ might decide to cancel. */ -+ -+ /* check whether the intr entry has been in the queue. */ -+ cpu_intr_save (&flags); -+ queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ if (e->notification_port == notification_port && e->line == line) -+ { -+ printf ("the interrupt entry for line %d and port %p " -+ "has already been inserted before.\n", -+ line, notification_port); -+ free = 1; -+ err = D_ALREADY_OPEN; -+ goto out; -+ } -+ queue_enter (&intr_queue, new, struct intr_entry *, chain); -+ out: -+ cpu_intr_restore (flags); -+ if (free) -+ { -+ ipc_port_dncancel (new->notification_port, (mach_port_t) 1, dnindex); -+ ip_unlock (new->notification_port); -+ ipc_port_release_sonce (dnnotify); -+ ipc_port_dealloc_kernel (new->port); -+ ipc_port_release_send (new->notification_port); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) new); -+ } -+ else -+ ip_unlock (new->notification_port); -+ -+ if (! err) -+ err = install_user_intr_handler (line, flags, new); -+ -+ return err; -+} -+ -+/* Lookup a intr_entry object by its port. */ -+static intr_entry_t -+intr_entry_port_lookup (ipc_port_t port) -+{ -+ struct intr_entry *entry; -+ -+ if (!IP_VALID(port)) -+ return 0; -+ -+ ip_lock (port); -+ if (ip_active (port) && (ip_kotype (port) == IKOT_INTR_ENTRY)) -+ entry = (struct intr_entry *) port->ip_kobject; -+ else -+ entry = 0; -+ ip_unlock (port); -+ return entry; -+} -+ -+/* Process a dead-name notification for a userspace interrupt handler -+ notification port. */ -+boolean_t -+intr_entry_notify (mach_msg_header_t *msg) -+{ -+ struct intr_entry *entry; -+ -+ if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS) -+ { -+ /* XXX uses internal Linux IRQ handling function. */ -+ extern void enable_irq (unsigned int irq_nr); -+ mach_no_senders_notification_t *ns; -+ -+ ns = (mach_no_senders_notification_t *) msg; -+ entry = intr_entry_port_lookup -+ ((ipc_port_t) ns->not_header.msgh_remote_port); -+ assert (entry); -+ -+ enable_irq (entry->line); -+ return TRUE; -+ } -+ else if (msg->msgh_id == MACH_NOTIFY_DEAD_NAME) -+ { -+ int line; -+ mach_dead_name_notification_t *dn; -+ unsigned long flags; -+ -+ dn = (mach_dead_name_notification_t *) msg; -+ entry = intr_entry_port_lookup -+ ((ipc_port_t) dn->not_header.msgh_remote_port); -+ assert (entry); -+ -+ cpu_intr_save (&flags); -+ line = entry->line; -+ assert (!queue_empty (&intr_queue)); -+ queue_remove (&intr_queue, entry, struct intr_entry *, chain); -+ remove_user_intr_handler (entry->line, entry); -+ cpu_intr_restore (flags); -+ -+ ipc_port_dealloc_kernel (entry->port); -+ ipc_port_release_send (entry->notification_port); -+ kmem_cache_free (&intr_entry_cache, (vm_offset_t) entry); -+ -+ printf ("irq handler %d: userspace handler died\n", line); -+ return TRUE; -+ } -+ -+ printf ("intr_entry_notify: strange notification %d\n", -+ msg->msgh_id); -+ return FALSE; -+} -+ -+ -+mach_intr_notification_t mach_intr_notification_template; -+ -+static void -+init_mach_intr_notification (mach_intr_notification_t *n) -+{ -+ mach_msg_header_t *m = &n->intr_header; -+ mach_msg_type_t *t = &n->line_type; -+ -+ m->msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_PORT_SEND, -+ MACH_MSG_TYPE_PORT_SEND); -+ m->msgh_size = sizeof *n; -+ m->msgh_seqno = INTR_NOTIFY_MSGH_SEQNO; -+ m->msgh_local_port = MACH_PORT_NULL; -+ m->msgh_remote_port = MACH_PORT_NULL; -+ m->msgh_id = MACH_INTR_NOTIFY; -+ -+ t->msgt_name = MACH_MSG_TYPE_INTEGER_32; -+ t->msgt_size = 32; -+ t->msgt_number = 1; -+ t->msgt_inline = TRUE; -+ t->msgt_longform = FALSE; -+ t->msgt_deallocate = FALSE; -+ t->msgt_unused = 0; -+} -+ -+static boolean_t -+deliver_intr (int line, ipc_port_t notification_port, ipc_port_t interrupt_port) -+{ -+ ipc_kmsg_t kmsg; -+ mach_intr_notification_t *n; -+ ipc_port_t sright, sonce, old; -+ -+ if (notification_port == IP_NULL) -+ return FALSE; -+ -+ if (interrupt_port == IP_NULL) -+ return FALSE; -+ -+ kmsg = ikm_alloc(sizeof *n); -+ if (kmsg == IKM_NULL) -+ return FALSE; -+ -+ ikm_init(kmsg, sizeof *n); -+ n = (mach_intr_notification_t *) &kmsg->ikm_header; -+ *n = mach_intr_notification_template; -+ -+ /* Arrange no-senders notification. */ -+ sright = ipc_port_make_send (interrupt_port); -+ sonce = ipc_port_make_sonce (interrupt_port); -+ ip_lock (interrupt_port); -+ ipc_port_nsrequest (interrupt_port, interrupt_port->ip_mscount, -+ sonce, &old); -+ if (old != IP_NULL) -+ ipc_port_release_sonce (old); -+ -+ n->intr_header.msgh_remote_port = (mach_port_t) notification_port; -+ n->intr_header.msgh_local_port = (mach_port_t) sright; -+ n->line = line; -+ -+ ipc_port_copy_send (notification_port); -+ ipc_mqueue_send_always (kmsg); -+ -+ return TRUE; -+} -+ -+void -+intr_thread () -+{ -+ queue_init (&intr_queue); -+ init_mach_intr_notification (&mach_intr_notification_template); -+ -+ kmem_cache_init (&intr_entry_cache, "intr_entry", -+ sizeof (struct intr_entry), 0, NULL, 0); -+ -+ for (;;) -+ { -+ struct intr_entry *e; -+ unsigned long flags; -+ assert_wait ((event_t) &intr_thread, FALSE); -+ cpu_intr_save (&flags); -+ -+ restart: -+ queue_iterate (&intr_queue, e, struct intr_entry *, chain) -+ if (e->interrupts) -+ { -+ int line = e->line; -+ ipc_port_t notification_port = e->notification_port; -+ ipc_port_t interrupt_port = e->port; -+ -+ assert (e->interrupts == 1); -+ e->interrupts--; -+ -+ cpu_intr_restore (flags); -+ deliver_intr (line, notification_port, interrupt_port); -+ cpu_intr_save (&flags); -+ -+ -+ /* We cannot assume that e still exists at this point -+ because we released the lock. Hence we restart the -+ iteration. */ -+ goto restart; -+ } -+ -+ cpu_intr_restore (flags); -+ thread_block (thread_no_continuation); -+ } -+} -+ -+#else /* MACH_XEN */ -+ -+boolean_t -+intr_entry_notify (mach_msg_header_t *msg) -+{ -+ panic ("not reached"); -+} -+ -+#endif /* MACH_XEN */ -diff --git a/include/device/intr.h b/include/device/intr.h -new file mode 100644 -index 0000000..34798b4 ---- /dev/null -+++ b/include/device/intr.h -@@ -0,0 +1,18 @@ -+#ifndef __INTR_H__ -+ -+#define __INTR_H__ -+ -+#include <device/device_types.h> -+ -+typedef struct -+{ -+ mach_msg_header_t intr_header; -+ mach_msg_type_t line_type; -+ int line; -+} mach_intr_notification_t; -+ -+ -+#define INTR_NOTIFY_MSGH_SEQNO 0 -+#define MACH_INTR_NOTIFY 424242 -+ -+#endif -diff --git a/include/mach/experimental.defs b/include/mach/experimental.defs -new file mode 100644 -index 0000000..16850df ---- /dev/null -+++ b/include/mach/experimental.defs -@@ -0,0 +1,98 @@ -+/* -+ * Mach Operating System -+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University -+ * All Rights Reserved. -+ * -+ * Permission to use, copy, modify and distribute this software and its -+ * documentation is hereby granted, provided that both the copyright -+ * notice and this permission notice appear in all copies of the -+ * software, derivative works or modified versions, and any portions -+ * thereof, and that both notices appear in supporting documentation. -+ * -+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" -+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR -+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. -+ * -+ * Carnegie Mellon requests users of this software to return to -+ * -+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU -+ * School of Computer Science -+ * Carnegie Mellon University -+ * Pittsburgh PA 15213-3890 -+ * -+ * any improvements or extensions that they make and grant Carnegie Mellon -+ * the rights to redistribute these changes. -+ */ -+ -+subsystem -+#if KERNEL_USER -+ KernelUser -+#endif /* KERNEL_USER */ -+#if KERNEL_SERVER -+ KernelServer -+#endif /* KERNEL_SERVER */ -+ experimental 424242; -+ -+#include <mach/std_types.defs> -+#include <mach/mach_types.defs> -+ -+serverprefix experimental_; -+ -+type notify_port_t = MACH_MSG_TYPE_MOVE_SEND_ONCE -+ ctype: mach_port_t; -+ -+skip; /*simpleroutine mach_intr_notify( -+ notify : notify_port_t; -+ name : int);*/ -+ -+routine device_intr_register( -+ master_port : mach_port_t; -+ in line : int; -+ in id : int; -+ in flags : int; -+ in receive_port : mach_port_send_t -+ ); -+/* JW: It doesn't look safe to pass flags through. dde sets -+ * SA_SHIRQ. -+ * -+ * ID seems unused. dde hands in 0. -+ */ -+ -+/* This no longer does anything. */ -+routine device_intr_enable( -+ master_port : mach_port_t; -+ line : int; -+ status : char); -+ -+/* -+ * 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); -diff --git a/kern/experimental.srv b/kern/experimental.srv -new file mode 100644 -index 0000000..2ccfd78 ---- /dev/null -+++ b/kern/experimental.srv -@@ -0,0 +1,3 @@ -+#define KERNEL_SERVER 1 -+ -+#include <mach/experimental.defs> -diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c -index 709ec9e..97c632a 100644 ---- a/kern/ipc_kobject.c -+++ b/kern/ipc_kobject.c -@@ -48,6 +48,7 @@ - #include <vm/vm_object.h> - #include <vm/memory_object_proxy.h> - #include <device/ds_routines.h> -+#include <device/interrupt.h> - - #include <kern/mach.server.h> - #include <ipc/mach_port.server.h> -@@ -56,6 +57,7 @@ - #include <device/device_pager.server.h> - #include <kern/mach4.server.h> - #include <kern/gnumach.server.h> -+#include <kern/experimental.server.h> - - #if MACH_DEBUG - #include <kern/mach_debug.server.h> -@@ -159,6 +161,7 @@ ipc_kobject_server(request) - * to perform the kernel function - */ - { -+ extern mig_routine_t experimental_server_routine(); - check_simple_locks(); - if ((routine = mach_server_routine(&request->ikm_header)) != 0 - || (routine = mach_port_server_routine(&request->ikm_header)) != 0 -@@ -170,6 +173,7 @@ ipc_kobject_server(request) - #endif /* MACH_DEBUG */ - || (routine = mach4_server_routine(&request->ikm_header)) != 0 - || (routine = gnumach_server_routine(&request->ikm_header)) != 0 -+ || (routine = experimental_server_routine(&request->ikm_header)) != 0 - #if MACH_MACHINE_ROUTINES - || (routine = MACHINE_SERVER_ROUTINE(&request->ikm_header)) != 0 - #endif /* MACH_MACHINE_ROUTINES */ -@@ -323,6 +327,10 @@ ipc_kobject_destroy( - vm_object_pager_wakeup(port); - break; - -+ case IKOT_INTR_ENTRY: -+ /* Do nothing. */ -+ break; -+ - default: - #if MACH_ASSERT - printf("ipc_kobject_destroy: port 0x%p, kobj 0x%lx, type %d\n", -@@ -365,6 +373,9 @@ ipc_kobject_notify(request_header, reply_header) - case IKOT_PAGER_PROXY: - return memory_object_proxy_notify(request_header); - -+ case IKOT_INTR_ENTRY: -+ return intr_entry_notify(request_header); -+ - default: - return FALSE; - } -diff --git a/kern/ipc_kobject.h b/kern/ipc_kobject.h -index 606a66a..6aefea7 100644 ---- a/kern/ipc_kobject.h -+++ b/kern/ipc_kobject.h -@@ -77,9 +77,10 @@ typedef unsigned int ipc_kobject_type_t; - #define IKOT_CLOCK 25 - #define IKOT_CLOCK_CTRL 26 - #define IKOT_PAGER_PROXY 27 -+#define IKOT_INTR_ENTRY 28 - /* << new entries here */ --#define IKOT_UNKNOWN 28 /* magic catchall */ --#define IKOT_MAX_TYPE 29 /* # of IKOT_ types */ -+#define IKOT_UNKNOWN 29 /* magic catchall */ -+#define IKOT_MAX_TYPE 30 /* # of IKOT_ types */ - /* Please keep ipc/ipc_object.c:ikot_print_array up to date */ - - #define is_ipc_kobject(ikot) (ikot != IKOT_NONE) -diff --git a/kern/startup.c b/kern/startup.c -index bd29694..0a571ff 100644 ---- a/kern/startup.c -+++ b/kern/startup.c -@@ -62,6 +62,7 @@ - #include <machine/model_dep.h> - #include <mach/version.h> - #include <device/device_init.h> -+#include <device/interrupt.h> - - #if MACH_KDB - #include <device/cons.h> -@@ -221,6 +222,9 @@ void start_kernel_threads(void) - (void) kernel_thread(kernel_task, reaper_thread, (char *) 0); - (void) kernel_thread(kernel_task, swapin_thread, (char *) 0); - (void) kernel_thread(kernel_task, sched_thread, (char *) 0); -+#ifndef MACH_XEN -+ (void) kernel_thread(kernel_task, intr_thread, (char *)0); -+#endif /* MACH_XEN */ - - #if NCPUS > 1 - /* -diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c -index 7753814..e2c18c7 100644 ---- a/linux/dev/arch/i386/kernel/irq.c -+++ b/linux/dev/arch/i386/kernel/irq.c -@@ -49,6 +49,7 @@ - - #include <linux/dev/glue/glue.h> - #include <machine/machspl.h> -+#include <device/interrupt.h> - - #if 0 - /* XXX: This is the way it's done in linux 2.2. GNU Mach currently uses intr_count. It should be made using local_{bh/irq}_count instead (through hardirq_enter/exit) for SMP support. */ -@@ -83,6 +84,7 @@ struct linux_action - void *dev_id; - struct linux_action *next; - unsigned long flags; -+ struct intr_entry *userspace_handler; - }; - - static struct linux_action *irq_action[16] = -@@ -113,7 +115,17 @@ linux_intr (int irq) - - while (action) - { -- action->handler (irq, action->dev_id, ®s); -+ // TODO I might need to check whether the interrupt belongs to -+ // the current device. But I don't do it for now. -+ if (action->userspace_handler) -+ { -+ /* We disable the irq here and it will be enabled -+ * after the interrupt is handled by the user space driver. */ -+ disable_irq (irq); -+ queue_intr (action->userspace_handler); -+ } -+ else if (action->handler) -+ action->handler (irq, action->dev_id, ®s); - action = action->next; - } - -@@ -233,6 +245,7 @@ setup_x86_irq (int irq, struct linux_action *new) - } - while (old); - shared = 1; -+ printk("store a new irq %d\n", irq); - } - - save_flags (flags); -@@ -250,6 +263,56 @@ setup_x86_irq (int irq, struct linux_action *new) - return 0; - } - -+int -+install_user_intr_handler (unsigned int irq, unsigned long flags, -+ struct intr_entry *entry) -+{ -+ struct linux_action *action; -+ int retval; -+ -+ assert (irq < 16); -+ -+ /* -+ * Hmm... Should I use `kalloc()' ? -+ * By OKUJI Yoshinori. -+ */ -+ action = (struct linux_action *) -+ linux_kmalloc (sizeof (struct linux_action), GFP_KERNEL); -+ if (action == NULL) -+ return linux_to_mach_error (-ENOMEM); -+ -+ action->handler = NULL; -+ action->next = NULL; -+ action->dev_id = NULL; -+ action->flags = flags; -+ action->userspace_handler = entry; -+ -+ retval = setup_x86_irq (irq, action); -+ if (retval) -+ linux_kfree (action); -+ -+ return linux_to_mach_error (retval); -+} -+ -+int -+remove_user_intr_handler (unsigned int irq, struct intr_entry *entry) -+{ -+ struct linux_action *action, **prev; -+ -+ for (prev = &irq_action[irq], action = irq_action[irq]; -+ action; -+ prev = &action->next, action = action->next) -+ if (action->userspace_handler == entry) -+ { -+ *prev = action->next; -+ linux_kfree(action); -+ enable_irq (irq); -+ return 1; -+ } -+ -+ return 0; -+} -+ - /* - * Attach a handler to an IRQ. - */ -@@ -278,6 +341,7 @@ request_irq (unsigned int irq, void (*handler) (int, void *, struct pt_regs *), - action->next = NULL; - action->dev_id = dev_id; - action->flags = flags; -+ action->userspace_handler = NULL; - - retval = setup_x86_irq (irq, action); - if (retval) -diff --git a/linux/dev/drivers/block/genhd.c b/linux/dev/drivers/block/genhd.c -index 3a86138..4a36f7f 100644 ---- a/linux/dev/drivers/block/genhd.c -+++ b/linux/dev/drivers/block/genhd.c -@@ -812,7 +812,9 @@ void device_setup(void) - #ifdef MACH - linux_intr_pri = SPL6; - #endif -- net_dev_init(); -+ extern char *kernel_cmdline; -+ if (!strstr(kernel_cmdline, " nonetdev")) -+ net_dev_init(); - #endif - #ifndef MACH - console_map_init(); -diff --git a/vm/vm_user.c b/vm/vm_user.c -index e65f6d5..788f43a 100644 ---- a/vm/vm_user.c -+++ b/vm/vm_user.c -@@ -449,3 +449,106 @@ kern_return_t vm_wire(port, map, start, size, access) - round_page(start+size), - access); - } -+ -+kern_return_t experimental_vm_allocate_contiguous(host_priv, map, result_vaddr, result_paddr, size) -+ host_t host_priv; -+ vm_map_t map; -+ vm_address_t *result_vaddr; -+ vm_address_t *result_paddr; -+ vm_size_t size; -+{ -+ unsigned int npages; -+ unsigned int i; -+ unsigned int order; -+ vm_page_t pages; -+ vm_object_t object; -+ vm_map_entry_t entry; -+ kern_return_t kr; -+ vm_address_t vaddr; -+ vm_offset_t offset = 0; -+ -+ if (host_priv == HOST_NULL) -+ return KERN_INVALID_HOST; -+ -+ if (map == VM_MAP_NULL) -+ return KERN_INVALID_TASK; -+ -+ /* -+ * XXX The page allocator returns blocks with a power-of-two size. -+ * The requested size may not be a power-of-two, causing the pages -+ * at the end of a block to be unused. In order to keep track of -+ * those pages, they must all be inserted in the VM object created -+ * by this function. -+ */ -+ order = vm_page_order(size); -+ size = (1 << (order + PAGE_SHIFT)); -+ -+ /* We allocate the contiguous physical pages for the buffer. */ -+ -+ npages = size / PAGE_SIZE; -+ pages = vm_page_grab_contig(size, VM_PAGE_SEL_DIRECTMAP); -+ if (pages == NULL) -+ { -+ return KERN_RESOURCE_SHORTAGE; -+ } -+ -+#if 0 -+ kr = vm_page_grab_contig(npages, pages, NULL, TRUE); -+ if (kr) -+ { -+ kfree (pages, npages * sizeof (vm_page_t)); -+ return kr; -+ } -+#endif -+ -+ /* Allocate the object -+ * and find the virtual address for the DMA buffer */ -+ -+ object = vm_object_allocate(size); -+ vm_map_lock(map); -+ /* TODO user_wired_count might need to be set as 1 */ -+ kr = vm_map_find_entry(map, &vaddr, size, (vm_offset_t) 0, -+ VM_OBJECT_NULL, &entry); -+ if (kr != KERN_SUCCESS) -+ { -+ vm_map_unlock(map); -+ vm_object_deallocate(object); -+ vm_page_free_contig(pages, size); -+ return kr; -+ } -+ -+ entry->object.vm_object = object; -+ entry->offset = 0; -+ -+ /* We can unlock map now. */ -+ vm_map_unlock(map); -+ -+ /* We have physical pages we need and now we need to do the mapping. */ -+ -+ pmap_pageable (map->pmap, vaddr, vaddr + size, FALSE); -+ -+ *result_vaddr = vaddr; -+ *result_paddr = pages->phys_addr; -+ -+ for (i = 0; i < npages; i++) -+ { -+ vm_object_lock(object); -+ vm_page_lock_queues(); -+ vm_page_insert(&pages[i], object, offset); -+ vm_page_wire(&pages[i]); -+ vm_page_unlock_queues(); -+ vm_object_unlock(object); -+ -+ /* Enter it in the kernel pmap */ -+ PMAP_ENTER(map->pmap, vaddr, &pages[i], VM_PROT_DEFAULT, TRUE); -+ -+ vm_object_lock(object); -+ PAGE_WAKEUP_DONE(&pages[i]); -+ vm_object_unlock(object); -+ -+ vaddr += PAGE_SIZE; -+ offset += PAGE_SIZE; -+ } -+ -+ return KERN_SUCCESS; -+} --- -2.1.4 - diff --git a/debian/patches/series b/debian/patches/series index 12a11d2..4480f3e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -9,4 +9,3 @@ task-load.patch reorder-ipc_port.patch sysenter0001-yyy-sysenter-prototype.patch -700002-70_new_dde.patch.patch |