summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-07-09 23:46:32 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-07-09 23:52:46 +0200
commit297950e5dad7b18d27bb6ab53d676524a744c979 (patch)
treef479d83504ccb456d8c405fd9cedbfcd3df6df62
parentaf36dbf3fd0cd065afadf0d8e7ae3aac39280bc4 (diff)
parente85ae9d7befbfe7a79235e68fb0423d40b6baf6c (diff)
Merge branch 'master-user_level_drivers2' into master-user_level_drivers2-debian
-rw-r--r--device/ds_routines.c4
-rw-r--r--device/intr.c11
-rw-r--r--device/intr.h3
-rw-r--r--include/device/notify.h2
-rw-r--r--linux/dev/arch/i386/kernel/irq.c.orig732
5 files changed, 11 insertions, 741 deletions
diff --git a/device/ds_routines.c b/device/ds_routines.c
index c36eeecd..c16b2098 100644
--- a/device/ds_routines.c
+++ b/device/ds_routines.c
@@ -340,7 +340,7 @@ ds_device_intr_register (device_t dev, int id,
if (! name_equal(mdev->dev_ops->d_name, 3, "irq"))
return D_INVALID_OPERATION;
- user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port);
+ user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port, 0);
if (!e)
return D_NO_MEMORY;
@@ -375,7 +375,7 @@ experimental_device_intr_register (ipc_port_t master_port, int line,
if (flags != 0x04000000)
return D_INVALID_OPERATION;
- user_intr_t *user_intr = insert_intr_entry (&irqtab, line, receive_port);
+ user_intr_t *user_intr = insert_intr_entry (&irqtab, line, receive_port, 1);
if (!user_intr)
return D_NO_MEMORY;
// TODO The original port should be replaced
diff --git a/device/intr.c b/device/intr.c
index 56f0c32c..a757b25c 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -24,7 +24,7 @@
#ifndef MACH_XEN
queue_head_t main_intr_queue;
-static boolean_t deliver_intr (int id, ipc_port_t dst_port);
+static boolean_t deliver_intr (int id, mach_msg_id_t msgh_id, ipc_port_t dst_port);
static user_intr_t *
search_intr (struct irqdev *dev, ipc_port_t dst_port)
@@ -113,7 +113,7 @@ deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e)
* This entry exists in the queue until
* the corresponding interrupt port is removed.*/
user_intr_t *
-insert_intr_entry (struct irqdev *dev, int id, ipc_port_t dst_port)
+insert_intr_entry (struct irqdev *dev, int id, ipc_port_t dst_port, int compat)
{
user_intr_t *e, *new, *ret;
int free = 0;
@@ -137,6 +137,7 @@ insert_intr_entry (struct irqdev *dev, int id, ipc_port_t dst_port)
new->id = id;
new->dst_port = dst_port;
new->interrupts = 0;
+ new->compat = compat;
queue_enter (dev->intr_queue, new, user_intr_t *, chain);
out:
@@ -207,7 +208,7 @@ intr_thread (void)
irqtab.tot_num_intr--;
splx (s);
- deliver_intr (id, dst_port);
+ deliver_intr (id, e->compat ? 424242 : DEVICE_INTR_NOTIFY, dst_port);
s = splhigh ();
}
}
@@ -236,7 +237,7 @@ intr_thread (void)
}
static boolean_t
-deliver_intr (int id, ipc_port_t dst_port)
+deliver_intr (int id, mach_msg_id_t msgh_id, ipc_port_t dst_port)
{
ipc_kmsg_t kmsg;
device_intr_notification_t *n;
@@ -260,7 +261,7 @@ deliver_intr (int id, ipc_port_t dst_port)
m->msgh_seqno = DEVICE_NOTIFY_MSGH_SEQNO;
m->msgh_local_port = MACH_PORT_NULL;
m->msgh_remote_port = MACH_PORT_NULL;
- m->msgh_id = DEVICE_INTR_NOTIFY;
+ m->msgh_id = msgh_id;
t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
t->msgt_size = 32;
diff --git a/device/intr.h b/device/intr.h
index cd3e0bce..bd639910 100644
--- a/device/intr.h
+++ b/device/intr.h
@@ -36,6 +36,7 @@ typedef struct {
int n_unacked; /* Number of times irqs were disabled for this */
ipc_port_t dst_port; /* Notification port */
int id; /* Mapping to machine dependent irq_t array elem */
+ int compat;
} user_intr_t;
struct irqdev {
@@ -52,7 +53,7 @@ struct irqdev {
extern queue_head_t main_intr_queue;
extern int install_user_intr_handler (struct irqdev *dev, int id, unsigned long flags, user_intr_t *e);
extern int deliver_user_intr (struct irqdev *dev, int id, user_intr_t *e);
-extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t receive_port);
+extern user_intr_t *insert_intr_entry (struct irqdev *dev, int id, ipc_port_t receive_port, int compat);
void intr_thread (void);
kern_return_t irq_acknowledge (ipc_port_t receive_port);
diff --git a/include/device/notify.h b/include/device/notify.h
index bd8d3a56..addf9114 100644
--- a/include/device/notify.h
+++ b/include/device/notify.h
@@ -29,6 +29,6 @@ typedef struct
int id;
} device_intr_notification_t;
-#define DEVICE_INTR_NOTIFY 424242
+#define DEVICE_INTR_NOTIFY 100
#endif /* _MACH_DEVICE_NOTIFY_H_ */
diff --git a/linux/dev/arch/i386/kernel/irq.c.orig b/linux/dev/arch/i386/kernel/irq.c.orig
deleted file mode 100644
index 75f8f812..00000000
--- a/linux/dev/arch/i386/kernel/irq.c.orig
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Linux IRQ management.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * 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, 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, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * linux/arch/i386/kernel/irq.c
- *
- * Copyright (C) 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-#include <mach/mach_types.h>
-#include <mach/vm_param.h>
-#include <kern/assert.h>
-
-#include <i386/spl.h>
-#include <i386/pic.h>
-#include <i386/pit.h>
-
-#define MACH_INCLUDE
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/delay.h>
-#include <linux/kernel_stat.h>
-#include <linux/malloc.h>
-#include <linux/ioport.h>
-
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/hardirq.h>
-
-#include <linux/dev/glue/glue.h>
-#include <machine/machspl.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. */
-unsigned int local_bh_count[NR_CPUS];
-unsigned int local_irq_count[NR_CPUS];
-#endif
-
-/*
- * XXX Move this into more suitable place...
- * Set if the machine has an EISA bus.
- */
-int EISA_bus = 0;
-
-/*
- * Flag indicating an interrupt is being handled.
- */
-unsigned int intr_count = 0;
-
-/*
- * List of Linux interrupt handlers.
- */
-struct linux_action
-{
- void (*handler) (int, void *, struct pt_regs *);
- void *dev_id;
- struct linux_action *next;
- unsigned long flags;
-};
-
-static struct linux_action *irq_action[16] =
-{
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
-};
-
-/*
- * Generic interrupt handler for Linux devices.
- * Set up a fake `struct pt_regs' then call the real handler.
- */
-static void
-linux_intr (int irq)
-{
- struct pt_regs regs;
- struct linux_action *action = *(irq_action + irq);
- unsigned long flags;
-
- kstat.interrupts[irq]++;
- intr_count++;
-
- save_flags (flags);
- if (action && (action->flags & SA_INTERRUPT))
- cli ();
-
- while (action)
- {
- action->handler (irq, action->dev_id, &regs);
- action = action->next;
- }
-
- restore_flags (flags);
-
- intr_count--;
-}
-
-/*
- * Mask an IRQ.
- */
-static inline void
-mask_irq (unsigned int irq_nr)
-{
- int new_pic_mask = curr_pic_mask | 1 << irq_nr;
-
- if (curr_pic_mask != new_pic_mask)
- {
- curr_pic_mask = new_pic_mask;
- if (irq_nr < 8)
- outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
- else
- outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
- }
-}
-
-/*
- * Unmask an IRQ.
- */
-static inline void
-unmask_irq (unsigned int irq_nr)
-{
- int mask;
- int new_pic_mask;
-
- mask = 1 << irq_nr;
- if (irq_nr >= 8)
- mask |= 1 << 2;
-
- new_pic_mask = curr_pic_mask & ~mask;
-
- if (curr_pic_mask != new_pic_mask)
- {
- curr_pic_mask = new_pic_mask;
- if (irq_nr < 8)
- outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
- else
- outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
- }
-}
-
-void
-disable_irq (unsigned int irq_nr)
-{
- unsigned long flags;
-
- assert (irq_nr < NR_IRQS);
-
- save_flags (flags);
- cli ();
- mask_irq (irq_nr);
- restore_flags (flags);
-}
-
-void
-enable_irq (unsigned int irq_nr)
-{
- unsigned long flags;
-
- assert (irq_nr < NR_IRQS);
-
- save_flags (flags);
- cli ();
- unmask_irq (irq_nr);
- restore_flags (flags);
-}
-
-static int
-setup_x86_irq (int irq, struct linux_action *new)
-{
- int shared = 0;
- struct linux_action *old, **p;
- unsigned long flags;
-
- p = irq_action + irq;
- if ((old = *p) != NULL)
- {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ))
- return (-EBUSY);
-
- /* Can't share interrupts unless both are same type */
- if ((old->flags ^ new->flags) & SA_INTERRUPT)
- return (-EBUSY);
-
- /* add new interrupt at end of irq queue */
- do
- {
- p = &old->next;
- old = *p;
- }
- while (old);
- shared = 1;
- }
-
- save_flags (flags);
- cli ();
- *p = new;
-
- if (!shared)
- {
- ivect[irq] = linux_intr;
- iunit[irq] = irq;
- unmask_irq (irq);
- }
- restore_flags (flags);
- return 0;
-}
-
-/*
- * Attach a handler to an IRQ.
- */
-int
-request_irq (unsigned int irq, void (*handler) (int, void *, struct pt_regs *),
- unsigned long flags, const char *device, void *dev_id)
-{
- struct linux_action *action;
- int retval;
-
- assert (irq < 16);
-
- if (!handler)
- return -EINVAL;
-
- /*
- * Hmm... Should I use `kalloc()' ?
- * By OKUJI Yoshinori.
- */
- action = (struct linux_action *)
- linux_kmalloc (sizeof (struct linux_action), GFP_KERNEL);
- if (action == NULL)
- return -ENOMEM;
-
- action->handler = handler;
- action->next = NULL;
- action->dev_id = dev_id;
- action->flags = flags;
-
- retval = setup_x86_irq (irq, action);
- if (retval)
- linux_kfree (action);
-
- return retval;
-}
-
-/*
- * Deallocate an irq.
- */
-void
-free_irq (unsigned int irq, void *dev_id)
-{
- struct linux_action *action, **p;
- unsigned long flags;
-
- if (irq > 15)
- panic ("free_irq: bad irq number");
-
- for (p = irq_action + irq; (action = *p) != NULL; p = &action->next)
- {
- if (action->dev_id != dev_id)
- continue;
-
- save_flags (flags);
- cli ();
- *p = action->next;
- if (!irq_action[irq])
- {
- mask_irq (irq);
- ivect[irq] = intnull;
- iunit[irq] = irq;
- }
- restore_flags (flags);
- linux_kfree (action);
- return;
- }
-
- panic ("free_irq: bad irq number");
-}
-
-/*
- * Set for an irq probe.
- */
-unsigned long
-probe_irq_on (void)
-{
- unsigned i, irqs = 0;
- unsigned long delay;
-
- assert (curr_ipl == 0);
-
- /*
- * Allocate all available IRQs.
- */
- for (i = 15; i > 0; i--)
- {
- if (!irq_action[i] && ivect[i] == intnull)
- {
- enable_irq (i);
- irqs |= 1 << i;
- }
- }
-
- /*
- * Wait for spurious interrupts to mask themselves out.
- */
- for (delay = jiffies + HZ / 10; delay > jiffies;)
- ;
-
- return (irqs & ~curr_pic_mask);
-}
-
-/*
- * Return the result of an irq probe.
- */
-int
-probe_irq_off (unsigned long irqs)
-{
- unsigned int i;
-
- assert (curr_ipl == 0);
-
- irqs &= curr_pic_mask;
-
- /*
- * Disable unnecessary IRQs.
- */
- for (i = 15; i > 0; i--)
- {
- if (!irq_action[i] && ivect[i] == intnull)
- {
- disable_irq (i);
- }
- }
-
- /*
- * Return IRQ number.
- */
- if (!irqs)
- return 0;
- i = ffz (~irqs);
- if (irqs != (irqs & (1 << i)))
- i = -i;
- return i;
-}
-
-/*
- * Reserve IRQs used by Mach drivers.
- * Must be called before Linux IRQ detection, after Mach IRQ detection.
- */
-
-static void reserved_mach_handler (int line, void *cookie, struct pt_regs *regs)
-{
- /* These interrupts are actually handled in Mach. */
- assert (! "reached");
-}
-
-static const struct linux_action reserved_mach =
- {
- reserved_mach_handler, NULL, NULL, 0
- };
-
-static void
-reserve_mach_irqs (void)
-{
- unsigned int i;
-
- for (i = 0; i < 16; i++)
- {
- if (ivect[i] != intnull)
- /* This dummy action does not specify SA_SHIRQ, so
- setup_x86_irq will not try to add a handler to this
- slot. Therefore, the cast is safe. */
- irq_action[i] = (struct linux_action *) &reserved_mach;
- }
-}
-
-#ifdef __SMP__
-unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile int global_irq_lock;
-atomic_t global_irq_count;
-
-atomic_t global_bh_count;
-atomic_t global_bh_lock;
-
-/*
- * "global_cli()" is a special case, in that it can hold the
- * interrupts disabled for a longish time, and also because
- * we may be doing TLB invalidates when holding the global
- * IRQ lock for historical reasons. Thus we may need to check
- * SMP invalidate events specially by hand here (but not in
- * any normal spinlocks)
- */
-#if 0
-/* XXX: check how Mach handles this */
-static inline void check_smp_invalidate(int cpu)
-{
- if (test_bit(cpu, &smp_invalidate_needed)) {
- clear_bit(cpu, &smp_invalidate_needed);
- local_flush_tlb();
- }
-}
-#endif
-
-static void show(char * str)
-{
- int i;
- unsigned long *stack;
- int cpu = smp_processor_id();
-
- printk("\n%s, CPU %d:\n", str, cpu);
- printk("irq: %d [%d %d]\n",
- atomic_read(&global_irq_count), local_irq_count[0], local_irq_count[1]);
- printk("bh: %d [%d %d]\n",
- atomic_read(&global_bh_count), local_bh_count[0], local_bh_count[1]);
- stack = (unsigned long *) &stack;
- for (i = 40; i ; i--) {
- unsigned long x = *++stack;
- //if (x > (unsigned long) &get_options && x < (unsigned long) &vsprintf) {
- printk("<[%08lx]> ", x);
- //}
- }
-}
-
-#define MAXCOUNT 100000000
-
-static inline void wait_on_bh(void)
-{
- int count = MAXCOUNT;
- do {
- if (!--count) {
- show("wait_on_bh");
- count = ~0;
- }
- /* nothing .. wait for the other bh's to go away */
- } while (atomic_read(&global_bh_count) != 0);
-}
-
-/*
- * I had a lockup scenario where a tight loop doing
- * spin_unlock()/spin_lock() on CPU#1 was racing with
- * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
- * apparently the spin_unlock() information did not make it
- * through to CPU#0 ... nasty, is this by design, do we have to limit
- * 'memory update oscillation frequency' artificially like here?
- *
- * Such 'high frequency update' races can be avoided by careful design, but
- * some of our major constructs like spinlocks use similar techniques,
- * it would be nice to clarify this issue. Set this define to 0 if you
- * want to check whether your system freezes. I suspect the delay done
- * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
- * i thought that such things are guaranteed by design, since we use
- * the 'LOCK' prefix.
- */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
-
-#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
-# define SYNC_OTHER_CORES(x) udelay(x+1)
-#else
-/*
- * We have to allow irqs to arrive between __sti and __cli
- */
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
-#endif
-
-static inline void wait_on_irq(int cpu)
-{
- int count = MAXCOUNT;
-
- for (;;) {
-
- /*
- * Wait until all interrupts are gone. Wait
- * for bottom half handlers unless we're
- * already executing in one..
- */
- if (!atomic_read(&global_irq_count)) {
- if (local_bh_count[cpu] || !atomic_read(&global_bh_count))
- break;
- }
-
- /* Duh, we have to loop. Release the lock to avoid deadlocks */
- clear_bit(0,&global_irq_lock);
-
- for (;;) {
- if (!--count) {
- show("wait_on_irq");
- count = ~0;
- }
- __sti();
- SYNC_OTHER_CORES(cpu);
- __cli();
- //check_smp_invalidate(cpu);
- if (atomic_read(&global_irq_count))
- continue;
- if (global_irq_lock)
- continue;
- if (!local_bh_count[cpu] && atomic_read(&global_bh_count))
- continue;
- if (!test_and_set_bit(0,&global_irq_lock))
- break;
- }
- }
-}
-
-/*
- * This is called when we want to synchronize with
- * bottom half handlers. We need to wait until
- * no other CPU is executing any bottom half handler.
- *
- * Don't wait if we're already running in an interrupt
- * context or are inside a bh handler.
- */
-void synchronize_bh(void)
-{
- if (atomic_read(&global_bh_count) && !in_interrupt())
- wait_on_bh();
-}
-
-/*
- * This is called when we want to synchronize with
- * interrupts. We may for example tell a device to
- * stop sending interrupts: but to make sure there
- * are no interrupts that are executing on another
- * CPU we need to call this function.
- */
-void synchronize_irq(void)
-{
- if (atomic_read(&global_irq_count)) {
- /* Stupid approach */
- cli();
- sti();
- }
-}
-
-static inline void get_irqlock(int cpu)
-{
- if (test_and_set_bit(0,&global_irq_lock)) {
- /* do we already hold the lock? */
- if ((unsigned char) cpu == global_irq_holder)
- return;
- /* Uhhuh.. Somebody else got it. Wait.. */
- do {
- do {
- //check_smp_invalidate(cpu);
- } while (test_bit(0,&global_irq_lock));
- } while (test_and_set_bit(0,&global_irq_lock));
- }
- /*
- * We also to make sure that nobody else is running
- * in an interrupt context.
- */
- wait_on_irq(cpu);
-
- /*
- * Ok, finally..
- */
- global_irq_holder = cpu;
-}
-
-#define EFLAGS_IF_SHIFT 9
-
-/*
- * A global "cli()" while in an interrupt context
- * turns into just a local cli(). Interrupts
- * should use spinlocks for the (very unlikely)
- * case that they ever want to protect against
- * each other.
- *
- * If we already have local interrupts disabled,
- * this will not turn a local disable into a
- * global one (problems with spinlocks: this makes
- * save_flags+cli+sti usable inside a spinlock).
- */
-void __global_cli(void)
-{
- unsigned int flags;
-
- __save_flags(flags);
- if (flags & (1 << EFLAGS_IF_SHIFT)) {
- int cpu = smp_processor_id();
- __cli();
- if (!local_irq_count[cpu])
- get_irqlock(cpu);
- }
-}
-
-void __global_sti(void)
-{
- int cpu = smp_processor_id();
-
- if (!local_irq_count[cpu])
- release_irqlock(cpu);
- __sti();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long __global_save_flags(void)
-{
- int retval;
- int local_enabled;
- unsigned long flags;
-
- __save_flags(flags);
- local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1;
- /* default to local */
- retval = 2 + local_enabled;
-
- /* check for global flags if we're not in an interrupt */
- if (!local_irq_count[smp_processor_id()]) {
- if (local_enabled)
- retval = 1;
- if (global_irq_holder == (unsigned char) smp_processor_id())
- retval = 0;
- }
- return retval;
-}
-
-void __global_restore_flags(unsigned long flags)
-{
- switch (flags) {
- case 0:
- __global_cli();
- break;
- case 1:
- __global_sti();
- break;
- case 2:
- __cli();
- break;
- case 3:
- __sti();
- break;
- default:
- printk("global_restore_flags: %08lx (%08lx)\n",
- flags, (&flags)[-1]);
- }
-}
-
-#endif
-
-static void (*old_clock_handler) ();
-
-void
-init_IRQ (void)
-{
- char *p;
- int latch = (CLKNUM + hz / 2) / hz;
-
- /*
- * Ensure interrupts are disabled.
- */
- (void) splhigh ();
-
- /*
- * Program counter 0 of 8253 to interrupt hz times per second.
- */
- outb_p (PIT_C0 | PIT_SQUAREMODE | PIT_READMODE, PITCTL_PORT);
- outb_p (latch & 0xff, PITCTR0_PORT);
- outb (latch >> 8, PITCTR0_PORT);
-
- /*
- * Install our clock interrupt handler.
- */
- old_clock_handler = ivect[0];
- ivect[0] = linux_timer_intr;
-
- reserve_mach_irqs ();
-
- /*
- * Enable interrupts.
- */
- (void) spl0 ();
-
- /*
- * Check if the machine has an EISA bus.
- */
- p = (char *) 0x0FFFD9;
- if (*p++ == 'E' && *p++ == 'I' && *p++ == 'S' && *p == 'A')
- EISA_bus = 1;
-
- /*
- * Permanently allocate standard device ports.
- */
- request_region (0x00, 0x20, "dma1");
- request_region (0x20, 0x20, "pic1");
- request_region (0x40, 0x20, "timer");
- request_region (0x70, 0x10, "rtc");
- request_region (0x80, 0x20, "dma page reg");
- request_region (0xa0, 0x20, "pic2");
- request_region (0xc0, 0x20, "dma2");
- request_region (0xf0, 0x10, "npu");
-}
-
-void
-restore_IRQ (void)
-{
- /*
- * Disable interrupts.
- */
- (void) splhigh ();
-
- /*
- * Restore clock interrupt handler.
- */
- ivect[0] = old_clock_handler;
-}
-