Index: linux22/Makefile
diff -u linux22/Makefile:1.1.1.3 linux22/Makefile:1.14
--- linux22/Makefile:1.1.1.3	Wed Oct 20 23:13:41 1999
+++ linux22/Makefile	Thu Nov 25 15:31:25 1999
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 13
-EXTRAVERSION =
+EXTRAVERSION =-rtl2.0
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -95,6 +95,10 @@
 ifdef CONFIG_SMP
 CFLAGS += -D__SMP__
 AFLAGS += -D__SMP__
+endif
+ifdef CONFIG_RTL
+CFLAGS += -D__RTL__
+AFLAGS += -D__RTL__
 endif
 
 #
Index: linux22/arch/i386/config.in
diff -u linux22/arch/i386/config.in:1.1.1.1 linux22/arch/i386/config.in:1.2
--- linux22/arch/i386/config.in:1.1.1.1	Thu Aug 12 22:06:27 1999
+++ linux22/arch/i386/config.in	Thu Aug 12 22:12:36 1999
@@ -40,6 +40,7 @@
 bool 'Math emulation' CONFIG_MATH_EMULATION
 bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
 bool 'Symmetric multi-processing support' CONFIG_SMP
+bool 'Hard realtime support' CONFIG_RTL
 endmenu
 
 mainmenu_option next_comment
Index: linux22/arch/i386/defconfig
diff -u linux22/arch/i386/defconfig:1.1.1.2 linux22/arch/i386/defconfig:1.2
--- linux22/arch/i386/defconfig:1.1.1.2	Wed Sep  1 20:10:18 1999
+++ linux22/arch/i386/defconfig	Thu Sep  2 08:24:14 1999
@@ -26,6 +26,7 @@
 # CONFIG_MATH_EMULATION is not set
 # CONFIG_MTRR is not set
 CONFIG_SMP=y
+CONFIG_RTL=y
 
 #
 # Loadable module support
Index: linux22/arch/i386/kernel/entry.S
diff -u linux22/arch/i386/kernel/entry.S:1.1.1.1 linux22/arch/i386/kernel/entry.S:1.2
--- linux22/arch/i386/kernel/entry.S:1.1.1.1	Thu Aug 12 22:06:29 1999
+++ linux22/arch/i386/kernel/entry.S	Thu Aug 12 22:12:36 1999
@@ -190,6 +190,9 @@
 	jne reschedule
 	cmpl $0,sigpending(%ebx)
 	jne signal_return
+#ifdef __RTL__
+	call __sti   #VY just checking
+#endif
 restore_all:
 	RESTORE_ALL
 
Index: linux22/arch/i386/kernel/io_apic.c
diff -u linux22/arch/i386/kernel/io_apic.c:1.1.1.2 linux22/arch/i386/kernel/io_apic.c:1.4
--- linux22/arch/i386/kernel/io_apic.c:1.1.1.2	Wed Oct 20 23:16:03 1999
+++ linux22/arch/i386/kernel/io_apic.c	Tue Oct 26 01:29:28 1999
@@ -1019,7 +1019,11 @@
 	if (irq < 16) {
 		disable_8259A_irq(irq);
 		if (i8259A_irq_pending(irq))
+#ifndef __RTL__
 			irq_desc[irq].status |= IRQ_PENDING;
+#else
+			rtl_global_pend_irq(irq);
+#endif
 	}
 	enable_edge_ioapic_irq(irq);
 }
@@ -1048,7 +1052,9 @@
 	 * Edge triggered IRQs can be acknowledged immediately
 	 * and do not need to be masked.
 	 */
+#ifndef __RTL__
 	ack_APIC_irq();
+#endif
 	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
 	status |= IRQ_PENDING;
 
@@ -1085,9 +1091,28 @@
 		spin_unlock(&irq_controller_lock);
 	}
 	desc->status &= ~IRQ_INPROGRESS;
+#ifdef __RTL__
+	if (!(desc->status & IRQ_DISABLED))/* need this cause RTL has soft_disabled*/
+			rtl_emulate_enable_irq(irq);
+#endif
 	spin_unlock(&irq_controller_lock);
 }
 
+#ifdef __RTL__
+/* RTL
+   moved this out of the do_level_ioapic code 
+   called by rtl_intercept
+   */
+static void mask_and_ack_edge_ioapic(unsigned int irq){
+	ack_APIC_irq();
+}
+static void mask_and_ack_level_ioapic(unsigned int irq)
+{
+	mask_IO_APIC_irq(irq);
+	ack_APIC_irq();
+}
+#endif /* __RTL__ */
+
 static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs)
 {
 	irq_desc_t *desc = irq_desc + irq;
@@ -1103,7 +1128,9 @@
 	 * disable has to happen before the ACK, to avoid IRQ storms.
 	 * So this all has to be within the spinlock.
 	 */
+#ifndef __RTL__
 	mask_IO_APIC_irq(irq);
+#endif
 	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
 
 	/*
@@ -1117,7 +1144,9 @@
 	}
 	desc->status = status;
 
+#ifndef __RTL__
 	ack_APIC_irq();
+#endif
 	spin_unlock(&irq_controller_lock);
 
 	/* Exit early if we had no action or it was disabled */
@@ -1129,7 +1158,11 @@
 	spin_lock(&irq_controller_lock);
 	desc->status &= ~IRQ_INPROGRESS;
 	if (!(desc->status & IRQ_DISABLED))
+#ifndef __RTL__
 		unmask_IO_APIC_irq(irq);
+#else
+		rtl_emulate_enable_irq(irq);/* RTL: can't touch hdwr*/
+#endif
 	spin_unlock(&irq_controller_lock);
 }
 
@@ -1149,6 +1182,9 @@
 	do_edge_ioapic_IRQ,
 	enable_edge_ioapic_irq,
 	disable_edge_ioapic_irq
+#ifdef __RTL__
+	,mask_and_ack_edge_ioapic
+#endif
 };
 
 static struct hw_interrupt_type ioapic_level_irq_type = {
@@ -1158,6 +1194,9 @@
 	do_level_ioapic_IRQ,
 	enable_level_ioapic_irq,
 	disable_level_ioapic_irq
+#ifdef __RTL__
+	,mask_and_ack_level_ioapic
+#endif
 };
 
 static inline void init_IO_APIC_traps(void)
Index: linux22/arch/i386/kernel/irq.c
diff -u linux22/arch/i386/kernel/irq.c:1.1.1.2 linux22/arch/i386/kernel/irq.c:1.28
--- linux22/arch/i386/kernel/irq.c:1.1.1.2	Wed Oct 20 23:16:03 1999
+++ linux22/arch/i386/kernel/irq.c	Thu Nov 25 01:03:25 1999
@@ -39,9 +39,134 @@
 #include <asm/pgtable.h>
 #include <asm/delay.h>
 #include <asm/desc.h>
+#include <asm/rtl_sync.h>
 
+
 #include "irq.h"
+#include <linux/cons.h>
+
+/* tracer */
+#ifdef CONFIG_RTL_TRACER
+void rtl_trace_default(int event_id, long event_data, long eip) { }
+void (*rtl_trace)(int event_id, long event_data, long eip) = rtl_trace_default;
+#endif
+
+/* Real Time Linux support */
+unsigned int rtl_intercept(struct pt_regs r);
+void rtl_emulate_enable_irq(unsigned int irq);
+void rtl_emulate_disable_irq(unsigned int irq);
+void rtl_emulate_shutdown_irq(unsigned int irq);
+void rtl_emulate_startup_irq(unsigned int irq);
+void rtl_make_sure_real_sti(const char *);
+
+#define RTL_L_IDLE_BIT 1
+#define RTL_L_IENABLE_BIT 4
+#define RTL_L_SINCE_STI_BIT 8
+#define RTL_L_IDLE_POS 0
+#define RTL_L_IENABLE_POS 2
+#define RTL_L_SINCE_STI_POS 3
+#define is_soft_sti() (RTL_LOCAL.flags & RTL_L_IENABLE_BIT)
+#define is_idle_realtime_system() (RTL_LOCAL.flags & RTL_L_IDLE_BIT)
+#define set_idle_realtime_system() set_bit(RTL_L_IDLE_POS,&RTL_LOCAL.flags)
+#define clear_idle_realtime_system() clear_bit(RTL_L_IDLE_POS,&RTL_LOCAL.flags)
+#define soft_cli() clear_bit(RTL_L_IENABLE_POS,&RTL_LOCAL.flags)
+#define soft_sti() set_bit(RTL_L_IENABLE_POS,&RTL_LOCAL.flags)
+
+/* assuming 255 global irqs and 31 max local smp vectors */
+#define IRQ_ARRAY_SIZE 4
+#define IRQ_ZINIT {0}
+#define IRQ_NZINIT {0xffffffff,0xffffffff,0xffffffff,0xffffffff}
+/* fix if IRQ_ARRAY_SIZE !=4  */
+#define irq_to_index(x)  ((x>>5)&3)
+#define irq_to_pos(x)  ((x)& 0x1fUL)
+#define irq_to_bit(x)  (1UL<< ((x) & 0x1f))
+#define pos_and_index_to_irq(p,i) ( (p) + (i*32))
+#ifdef __SMP__
+struct rtl_local {
+	__u32    flags;
+	__u32    pending;
+}rtl_local[NR_CPUS] = { {RTL_L_IDLE_BIT ,0},{RTL_L_IDLE_BIT,0}};
+#define RTL_LOCAL rtl_local[cpu_id]
+#define active_local_irqs() (RTL_LOCAL.pending)
+#define active_irqs() (active_local_irqs() || active_global_irqs())
+#define DeclareAndInit(cpu_id)  unsigned int cpu_id = smp_processor_id()
+#define HardDeclareAndInit(cpu_id)  unsigned int cpu_id = hard_smp_processor_id()
+void rtl_local_pend_vec(int vector,int cpu_id) {
+		        int i = VECTOR_TO_LOCAL_PND(vector);
+			set_bit(i,&(RTL_LOCAL.pending));
+	                set_bit(RTL_L_SINCE_STI_POS, &RTL_LOCAL.flags);
+}
+#else
+#define DeclareAndInit(cpu_id)
+#define HardDeclareAndInit(cpu_id)
+struct rtl_local {
+	__u32 flags;
+} rtl_local = {RTL_L_IENABLE_BIT | RTL_L_IDLE_BIT};
+#define RTL_LOCAL rtl_local
+#endif
+
+
+struct rtl_global{
+	spinlock_t hard_irq_controller_lock;
+	unsigned int rtl_off;
+	unsigned int pending[IRQ_ARRAY_SIZE];
+	unsigned int soft_enabled[IRQ_ARRAY_SIZE];
+	unsigned int rt_system_is_idle;
+	unsigned int rtirq[IRQ_ARRAY_SIZE];
+	unsigned int pended_since_sti;
+};
+struct rtl_global rtl_global ={ SPIN_LOCK_UNLOCKED,1,IRQ_ZINIT,IRQ_NZINIT,1,IRQ_ZINIT,0} ;
+
+/* macros for touching the global structure */
+#define test_g(ix,y) test_bit(irq_to_pos(ix),&y[irq_to_index(ix)])
+#define global_is_pending_irq(ix) test_g(ix,rtl_global.pending)
+#define global_is_enabled_irq(ix) test_g(ix,rtl_global.soft_enabled)
+#define there_is_a_rt_handler(ix) test_g(ix,rtl_global.rtirq) 
+#define global_pend_irq(ix)\
+       set_bit(irq_to_pos(ix),&rtl_global.pending[irq_to_index(ix)])
+#define global_unpend_irq(ix) \
+	{clear_bit(irq_to_pos(ix),&rtl_global.pending[irq_to_index(ix)]);}
+#define atomic_global_soft_disable(x) \
+      clear_bit(irq_to_pos(x),&rtl_global.soft_enabled[irq_to_index(x)]);
+#define global_soft_enable(x) \
+      set_bit(irq_to_pos(x),&rtl_global.soft_enabled[irq_to_index(x)]);
 
+
+
+/* this are exported so that they can be called by rt drivers */
+void rtl_global_pend_irq(int ix) { global_pend_irq(ix);}
+void rtl_hard_enable_irq(unsigned int ix) { 
+	int flags;
+       	rtl_hard_savef_and_cli(flags);
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	irq_desc[ix].handler->enable(ix);
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_hard_restore_flags(flags);
+}
+void rtl_hard_disable_irq(unsigned int ix) { 
+	int flags;
+       	rtl_hard_savef_and_cli(flags);
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	irq_desc[ix].handler->disable(ix);
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_hard_restore_flags(flags);
+}
+ 
+unsigned int rtl_rt_system_is_idle(){ 
+	HardDeclareAndInit(cpu_id);
+	return is_idle_realtime_system();
+}
+/* needs to be called with irqs disabled */
+void rtl_make_rt_system_active(){ 
+	HardDeclareAndInit(cpu_id);
+	clear_idle_realtime_system();
+}
+/* needs to be called with irqs disabled */
+void rtl_make_rt_system_idle(){ 
+	HardDeclareAndInit(cpu_id);
+	set_idle_realtime_system();
+}
+
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 
@@ -111,7 +236,36 @@
 	shutdown_none,
 	do_none,
 	enable_none,
-	disable_none
+	disable_none,0
+};
+
+/*
+ * Dummy controller type for RTL soft interrupts
+ */
+static void rtl_do_none(unsigned int irq, struct pt_regs * regs)
+{
+	struct irqaction * action;
+	irq_desc_t *desc = irq_desc + irq;
+
+	action = desc->action;
+	if (!action)
+		return;
+	handle_IRQ_event(irq, regs, action);
+}
+static void rtl_enable_none(unsigned int irq) { }
+static void rtl_disable_none(unsigned int irq) { }
+
+/* startup is the same as "enable", shutdown is same as "disable" */
+#define rtl_startup_none	rtl_enable_none
+#define rtl_shutdown_none	rtl_disable_none
+
+struct hw_interrupt_type rtl_soft_irq_type = {
+	"rtl-soft",
+	rtl_startup_none,
+	rtl_shutdown_none,
+	rtl_do_none,
+	rtl_enable_none,
+	rtl_disable_none,0
 };
 
 /*
@@ -126,14 +280,15 @@
 /* startup is the same as "enable", shutdown is same as "disable" */
 #define startup_8259A_irq	enable_8259A_irq
 #define shutdown_8259A_irq	disable_8259A_irq
-
+static inline void mask_and_ack_8259A(unsigned int irq);
 static struct hw_interrupt_type i8259A_irq_type = {
 	"XT-PIC",
 	startup_8259A_irq,
 	shutdown_8259A_irq,
 	do_8259A_IRQ,
 	enable_8259A_irq,
-	disable_8259A_irq
+	disable_8259A_irq,
+	mask_and_ack_8259A
 };
 
 /*
@@ -215,7 +370,8 @@
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static inline void mask_and_ack_8259A(unsigned int irq)
+/* RTL can't inline this yet, since we put the pointer in the desc */
+static void mask_and_ack_8259A(unsigned int irq)
 {
 	cached_irq_mask |= 1 << irq;
 	if (irq & 8) {
@@ -238,7 +394,6 @@
 	spin_lock(&irq_controller_lock);
 	{
 		unsigned int status;
-		mask_and_ack_8259A(irq);
 		status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
 		action = NULL;
 		if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
@@ -252,15 +407,16 @@
 	/* Exit early if we had no action or it was disabled */
 	if (!action)
 		return;
-
 	handle_IRQ_event(irq, regs, action);
+	__cli(); /* RTL just to make sure */
 
 	spin_lock(&irq_controller_lock);
 	{
 		unsigned int status = desc->status & ~IRQ_INPROGRESS;
 		desc->status = status;
-		if (!(status & IRQ_DISABLED))
-			enable_8259A_irq(irq);
+		if (!(status & IRQ_DISABLED)){
+			rtl_emulate_enable_irq(irq);/* RTL: can't touch hdwr*/
+		}
 	}
 	spin_unlock(&irq_controller_lock);
 }
@@ -319,11 +475,13 @@
  * is no hardware IRQ pin equivalent for them, they are triggered
  * through the ICC by us (IPIs)
  */
-BUILD_SMP_INTERRUPT(reschedule_interrupt)
-BUILD_SMP_INTERRUPT(invalidate_interrupt)
-BUILD_SMP_INTERRUPT(stop_cpu_interrupt)
-BUILD_SMP_INTERRUPT(call_function_interrupt)
-BUILD_SMP_INTERRUPT(spurious_interrupt)
+BUILD_COMMON_SMP_IRQ() /* RTL needs to have a common path */
+BUILD_SMP_INTERRUPT(RESCHEDULE_VECTOR,reschedule_interrupt)
+BUILD_SMP_INTERRUPT(INVALIDATE_TLB_VECTOR,invalidate_interrupt)
+BUILD_SMP_INTERRUPT(STOP_CPU_VECTOR,stop_cpu_interrupt)
+BUILD_SMP_INTERRUPT(SPURIOUS_APIC_VECTOR,spurious_interrupt)
+BUILD_SMP_INTERRUPT(CALL_FUNCTION_VECTOR,call_function_interrupt)
+  
 
 /*
  * every pentium local APIC has two 'local interrupts', with a
@@ -332,7 +490,8 @@
  * overflow. Linux uses the local APIC timer interrupt to get
  * a much simpler SMP time architecture:
  */
-BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt)
+BUILD_SMP_TIMER_INTERRUPT(LOCAL_TIMER_VECTOR,apic_timer_interrupt)
+BUILD_SMP_TIMER_INTERRUPT(RTL_RESCHEDULE_VECTOR,rtl_resched_interrupt)
 
 #endif
 
@@ -349,10 +508,10 @@
 	IRQLIST_16(0x0),
 
 #ifdef CONFIG_X86_IO_APIC
-	                 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
-	IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
+	                 IRQLIST_16(0x1)/*, IRQLIST_16(0x2), IRQLIST_16(0x3),
+	IRQLIST_16(0x4) , IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
 	IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
-	IRQLIST_16(0xc), IRQLIST_16(0xd)
+	IRQLIST_16(0xc), IRQLIST_16(0xd) */
 #endif
 };
 
@@ -758,7 +917,7 @@
 	spin_lock_irqsave(&irq_controller_lock, flags);
 	if (!irq_desc[irq].depth++) {
 		irq_desc[irq].status |= IRQ_DISABLED;
-		irq_desc[irq].handler->disable(irq);
+		rtl_emulate_disable_irq(irq); /* RTL: hands off hdwr*/
 	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
@@ -781,12 +940,13 @@
 void enable_irq(unsigned int irq)
 {
 	unsigned long flags;
+ 	DeclareAndInit(cpu_id);
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
 	switch (irq_desc[irq].depth) {
 	case 1:
 		irq_desc[irq].status &= ~IRQ_DISABLED;
-		irq_desc[irq].handler->enable(irq);
+ 		rtl_emulate_enable_irq(irq); /*RTL: hands off hrdwr */
 		/* fall throught */
 	default:
 		irq_desc[irq].depth--;
@@ -796,6 +956,7 @@
 		       __builtin_return_address(0));
 	}
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
+	if(is_soft_sti())__sti();
 }
 
 /*
@@ -803,23 +964,15 @@
  * SMP cross-CPU interrupts have their own specific
  * handlers).
  */
-asmlinkage void do_IRQ(struct pt_regs regs)
+/* For RTL call with pointer to regs and with irq number already
+   calculated by rtl_intercept or by fake_irq
+   */
+void do_IRQ(unsigned int irq, struct pt_regs *regs)
 {	
-	/* 
-	 * We ack quickly, we don't want the irq controller
-	 * thinking we're snobs just because some other CPU has
-	 * disabled global interrupts (we have already done the
-	 * INT_ACK cycles, it's too late to try to pretend to the
-	 * controller that we aren't taking the interrupt).
-	 *
-	 * 0 return value means that this irq is already being
-	 * handled by some other CPU. (or is disabled)
-	 */
-	int irq = regs.orig_eax & 0xff; /* subtle, see irq.h */
 	int cpu = smp_processor_id();
 
 	kstat.irqs[cpu][irq]++;
-	irq_desc[irq].handler->handle(irq, &regs);
+	irq_desc[irq].handler->handle(irq, regs);
 
 	/*
 	 * This should be conditional: we should really get
@@ -881,12 +1034,32 @@
 	if (!shared) {
 		irq_desc[irq].depth = 0;
 		irq_desc[irq].status &= ~IRQ_DISABLED;
-		irq_desc[irq].handler->startup(irq);
+ 		rtl_emulate_startup_irq(irq); /* RTL: hands off hardware*/
 	}
 	spin_unlock_irqrestore(&irq_controller_lock,flags);
 	return 0;
 }
 
+/* VY: needs some synchronization here. Doesn't request_irq also
+   have a problem? */
+int rtl_get_soft_irq (void (*handler) (int, void *, struct pt_regs *),
+		      const char *devname)
+{
+	int i;
+	for (i = NR_IRQS - 1; i > 15; i--) {
+		if (!irq_desc[i].action) {
+			irq_desc[i].handler = &rtl_soft_irq_type;
+			if (request_irq (i, handler, 0, devname, 0)) {
+				return -EBUSY;
+			} else {
+				global_soft_enable(i);
+				return i;
+			}
+		}
+	}
+	return -1;
+}
+
 int request_irq(unsigned int irq, 
 		void (*handler)(int, void *, struct pt_regs *),
 		unsigned long irqflags, 
@@ -949,7 +1122,7 @@
 		kfree(action);
 		if (!irq_desc[irq].action) {
 			irq_desc[irq].status |= IRQ_DISABLED;
-			irq_desc[irq].handler->shutdown(irq);
+			rtl_emulate_shutdown_irq(irq);/*RTL hands off hardware*/
 		}
 		goto out;
 	}
@@ -978,7 +1151,7 @@
 	for (i = NR_IRQS-1; i > 0; i--) {
 		if (!irq_desc[i].action) {
 			irq_desc[i].status |= IRQ_AUTODETECT | IRQ_WAITING;
-			irq_desc[i].handler->startup(i);
+ 			rtl_emulate_startup_irq(i); /* RTL hands off hardware*/
 		}
 	}
 	spin_unlock_irq(&irq_controller_lock);
@@ -1002,7 +1175,8 @@
 		/* It triggered already - consider it spurious. */
 		if (!(status & IRQ_WAITING)) {
 			irq_desc[i].status = status & ~IRQ_AUTODETECT;
-			irq_desc[i].handler->shutdown(i);
+			rtl_emulate_shutdown_irq(i);
+/* 		conpr("SSh"); conprn(i); */
 		}
 	}
 	spin_unlock_irq(&irq_controller_lock);
@@ -1032,7 +1206,7 @@
 			nr_irqs++;
 		}
 		irq_desc[i].status = status & ~IRQ_AUTODETECT;
-		irq_desc[i].handler->shutdown(i);
+		rtl_emulate_shutdown_irq(i);
 	}
 	spin_unlock_irq(&irq_controller_lock);
 
@@ -1064,6 +1238,16 @@
 	}
 }
 
+#ifdef __SMP__
+/* RTL needs this */
+void  smp_reschedule_interrupt(void);
+void  smp_invalidate_interrupt(void);
+void  smp_stop_cpu_interrupt(void);
+void  smp_apic_timer_interrupt(struct pt_regs *);
+void  smp_spurious_interrupt(void);
+void  smp_call_function_interrupt(void);
+#endif /* SMP */
+
 __initfunc(void init_IRQ(void))
 {
 	int i;
@@ -1112,6 +1296,9 @@
 
 	/* IPI vector for APIC spurious interrupts */
 	set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
+#ifdef __RTL__
+ 	set_intr_gate(RTL_RESCHEDULE_VECTOR, rtl_resched_interrupt);
+#endif
 #endif	
 	request_region(0x20,0x20,"pic1");
 	request_region(0xa0,0x20,"pic2");
@@ -1138,5 +1325,525 @@
 		if (IO_APIC_VECTOR(i) > 0)
 			set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]);
 }
+#endif
+
+
+
+/* these should only be called from Linux kernel so they need
+   to hard cli/sti -- I'm saving out of sloppiness, they should never
+   be called with hard cli.
+   */
+void rtl_emulate_shutdown_irq(unsigned int irq){ rtl_emulate_disable_irq(irq);}
+
+void rtl_emulate_disable_irq(unsigned int irq){
+	if(rtl_global.rtl_off){
+		irq_desc[irq].handler->disable(irq);
+		return;
+	}
+
+	/* don't actually disable here. We are optimistic and
+	   only mask/disable in intercept */
+        atomic_global_soft_disable(irq);
+}
+void rtl_emulate_startup_irq(unsigned int irq){
+	int flags;
+	if(rtl_global.rtl_off){
+		irq_desc[irq].handler->startup(irq);
+		global_soft_enable(irq);
+		return;
+	}
+       	rtl_hard_savef_and_cli(flags);
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	global_soft_enable(irq);
+	irq_desc[irq].handler->startup(irq); /* start it whether pending or
+						not */
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_hard_restore_flags(flags);
+}
+void rtl_emulate_enable_irq(unsigned int irq){
+	int flags;
+	if(rtl_global.rtl_off){
+		irq_desc[irq].handler->enable(irq);
+		global_soft_enable(irq);
+		return;
+	}
+       	rtl_hard_savef_and_cli(flags);
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	global_soft_enable(irq);
+	if(!global_is_pending_irq(irq)){
+		irq_desc[irq].handler->enable(irq);
+	}
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_hard_restore_flags(flags);
+}
+
+void rtl_test_cli(unsigned int *);
+#define IENABLE 0x200 /* need to have the actual bit set since global_cli and
+			 global_save_flags etc look at it */
+void __cli(void) {
+	DeclareAndInit(cpu_id);
+	if(rtl_global.rtl_off)rtl_hard_cli();
+	soft_cli();
+}
+void __restore_flags(unsigned int x) { 
+	DeclareAndInit(cpu_id);
+	if(rtl_global.rtl_off){
+       	        if(x& IENABLE) {
+                      soft_sti();
+		      rtl_hard_sti();
+		}
+		else  { 
+			soft_cli();
+			rtl_hard_cli();
+		}
+		return;
+	}
+	if(x)__sti();
+	else __cli();
+}
+unsigned int __return_flags(void) {
+	DeclareAndInit(cpu_id);
+	if(rtl_global.rtl_off) {
+		unsigned int y;
+		rtl_hard_save_flags(y);
+		if(y & 0x200) soft_sti();
+		else soft_cli();
+	}
+	return ((RTL_LOCAL.flags & RTL_L_IENABLE_BIT)? IENABLE:0);
+}
+/* DIAGNOSTICS */
+
+/* Diagnostics */
+void rtl_test_cli(unsigned int *x)
+{
+	unsigned long g,j;
+	HardDeclareAndInit(cpu_id);
+	rtl_hard_save_flags(g);
+	g = (g&0x200? 1: 0);
+        j =  (RTL_LOCAL.flags & RTL_L_IENABLE_BIT ? 1: 0);
+	if( g != j)
+	{
+	printk("RTL g: x %p x-1:%x x-2:%x\n",x,*( (int *)x -1),*((int *)x -2));
+	}
+	return;
+}
+	
+void do_rtl_debug(void){
+	unsigned long g;
+	HardDeclareAndInit(cpu_id);
+	rtl_hard_save_flags(g);
+	rtl_hard_cli();
+	conpr("\nflags="); conprn(g);
+#ifdef __SMP__
+	conpr("\nProcessor="); conprn(cpu_id);
+	conpr("\nGlobal hard_irq_controller_lock=");
+	conprn(rtl_global.hard_irq_controller_lock.lock);
+#endif // __SMP__
+conpr("\npending 0;"); conprn(rtl_global.pending[0]);
+conpr("\nrtl_off;"); conprn(rtl_global.rtl_off);
+conpr("\nsoft_enabled 0 ;"); conprn(rtl_global.soft_enabled[0]);
+conpr("\nrtirq 0;"); conprn(rtl_global.rtirq[0]);
+conpr("\nlocal flags;"); conprn(RTL_LOCAL.flags);
+conpr("\ncached irq flags="); conprn(cached_irq_mask);
+conpr("----------------\n");
+	//outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+//	outb_p(LATCH & 0xff , 0x40);	/* LSB */
+//	outb(LATCH >> 8 , 0x40);	/* MSB */
+rtl_hard_restore_flags(g);
+
+}
+	
+void rtl_panic(const char *x)
+{
+	conpr("\nPANIC "); conpr(x);
+	do_rtl_debug();
+	while(1);
+}
+void rtl_test_timer(unsigned char *s)
+{
+	unsigned long g;
+	if(rtl_global.rtl_off)return;
+	rtl_hard_save_flags(g);
+	conpr(s);
+	g = (g&0x200? 1: 0);
+	if(!g)
+	{
+	conpr("real cli in "); conpr(s); conpr("\n");
+	}
+	if(!(rtl_global.soft_enabled[0] & 1)){
+		conpr("no timer enable:"); conpr(s); conpr("\n");
+		conpr("pending=:"); conprn(rtl_global.pending[0]); conpr("\n");
+	}
+
+}
+void rtl_make_sure_real_sti(const char *s){
+	unsigned long g;
+	if(rtl_global.rtl_off)return;
+	rtl_hard_save_flags(g);
+	g = (g&0x200? 1: 0);
+	if(!g)
+	{
+	conpr("real cli in "); conpr(s); conpr("\n");
+	}
+	return;
+}
+
+int rtltc(void)
+{
+	unsigned long g;
+	rtl_hard_save_flags(g);
+	return (g&0x200? 1: 0);
+}
+	
+
+/* INTERCEPTS */
+/* this intercepts SMP irqs */
+#ifdef __SMP__
+
+static inline void do_local_irq(int , struct pt_regs *);
+
+static unsigned int default_local_timer_handler(struct pt_regs *r)
+{
+	HardDeclareAndInit(cpu_id);
+	rtl_local_pend_vec(LOCAL_TIMER_VECTOR,cpu_id);
+	return 0;
+}
+
+static unsigned int default_local_resched_handler(struct pt_regs *r)
+{
+	return 0;
+}
+
+struct rtl_local_handlers local_timer_handler[NR_CPUS] = {{default_local_timer_handler}, {default_local_timer_handler}};
+struct rtl_local_handlers local_resched_handler[NR_CPUS] = {{default_local_resched_handler}, {default_local_resched_handler}};
+
+unsigned int rtl_smp_intercept(struct pt_regs regs){
+	unsigned int vector = regs.orig_eax & 0xff;
+	HardDeclareAndInit(cpu_id);
+	ack_APIC_irq();
+
+	rtl_trace(RTL_TRACE_SMP_INTERCEPT, vector, regs.eip);
+       
+	if(rtl_global.rtl_off){
+		rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+		soft_cli();
+		do_local_irq(vector,&regs);
+		soft_sti();
+		return 0;
+	}
+
+	switch (vector) {
+		case RTL_RESCHEDULE_VECTOR:
+			local_resched_handler[cpu_id].handler(&regs);
+			rtl_trace(RTL_TRACE_SMP_INTERCEPT_EXIT, vector, regs.eip);
+			return 1;
+		case LOCAL_TIMER_VECTOR:
+			local_timer_handler[cpu_id].handler(&regs);
+			break;
+		case INVALIDATE_TLB_VECTOR:
+		case STOP_CPU_VECTOR:
+		case CALL_FUNCTION_VECTOR:
+		case RESCHEDULE_VECTOR:
+			rtl_local_pend_vec(vector,cpu_id);
+			break;
+		default:
+			conpr("RTL unexpected local vector: ");
+			conprn(vector);
+			return 1;
+	}
+		
+
+	if((regs.eflags & 0x200) && is_idle_realtime_system() && is_soft_sti())
+	{
+		soft_cli();
+		rtl_hard_sti(); /* yikes */
+		__sti(); /* handle any pending interrupts */
+		rtl_trace(RTL_TRACE_SMP_INTERCEPT_EXIT, vector, regs.eip);
+		return 0;
+	}
+	else return 1;
+}
+static inline void do_local_irq(int vector, struct pt_regs *regs){
+	switch(vector){
+	/* IPI for rescheduling */
+		case RESCHEDULE_VECTOR:
+			smp_reschedule_interrupt();
+			break;
+			/* IPI for invalidation */
+		case INVALIDATE_TLB_VECTOR:
+			smp_invalidate_interrupt();
+			break;
+			/* IPI for CPU halt */
+		case STOP_CPU_VECTOR:
+			smp_stop_cpu_interrupt();
+			break;
+			/* self generated IPI for local APIC timer */
+		case LOCAL_TIMER_VECTOR:
+			smp_apic_timer_interrupt(regs);
+			break;
+			/* IPI for function call  control */
+		case CALL_FUNCTION_VECTOR:
+			smp_call_function_interrupt();
+			break;
+			/* IPI vector for APIC spurious interrupts */
+		case SPURIOUS_APIC_VECTOR:
+			smp_spurious_interrupt();
+			break;
+		default:
+			printk("RTL: bad smp vector %x\n",vector);
+			break;
+	}
+}
+
+#endif
+
+unsigned int rtl_intercept(struct pt_regs regs)
+{
+	unsigned int irq = regs.orig_eax & 0xff;
+	HardDeclareAndInit(cpu_id);
+	
+	rtl_trace(RTL_TRACE_INTERCEPT, irq, regs.eip);
+	/* 
+	 * We ack quickly, we don't want the irq controller
+	 * thinking we're snobs just because some other CPU has
+	 * disabled global interrupts (we have already done the
+	 * INT_ACK cycles, it's too late to try to pretend to the
+	 * controller that we aren't taking the interrupt).
+	 *
+	 * 0 return value means that this irq is already being
+	 * handled by some other CPU. (or is disabled)
+	 */
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	irq_desc[irq].handler->mask_and_ack(irq);
+	if(rtl_global.rtl_off){
+		rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+		soft_cli();
+		do_IRQ(irq,&regs);
+		soft_sti();
+		return 0;
+	}
+	/* if there is a real time handler, call it and see if it is
+	   willing to share the interrupt */
+	if(there_is_a_rt_handler(irq) && rtl_global_handlers[irq].handler)
+	{
+		rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+		rtl_global_handlers[irq].handler(irq,&regs);
+		rtl_hard_cli(); /* driver may have hard sti'd */
+		rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+		if(!global_is_pending_irq(irq)){/* does linux need it? */
+			rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+			rtl_trace2(RTL_TRACE_INTERCEPT_EXIT, irq);
+			return 1;
+		}
+	} 
+	else {
+		global_pend_irq(irq); /*note structure is locked */
+	}
+	if(  is_soft_sti() && is_idle_realtime_system()
+			&& global_is_enabled_irq(irq))
+	{
+		global_unpend_irq(irq); /* because we call do_IRQ */
+		soft_cli(); /*soft disable interrupts */
+		rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+		rtl_hard_sti(); /* yikes */
+		do_IRQ(irq,&regs);
+		__sti(); /* take care of any left over irqs */
+			       
+		rtl_trace2(RTL_TRACE_INTERCEPT_EXIT, irq);
+		return 0;
+	}
+	rtl_global.pended_since_sti = 1;
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_trace2(RTL_TRACE_INTERCEPT_EXIT, irq);
+	return 1;
+	
+}
+
+
+
+/* pt_regs 
+long ebx= 0, long ecx=0, long edx=0, long esi=0, long edi=0,
+long ebp=0, long eax=0, int  xds= __KERNEL_DS, int  xes=0, long orig_eax=0,
+long eip= (long)__sti, int  xcs= __KERNEL_CS, long eflags= IENABLE,
+long esp=0, int  xss=0
+*/
+#define FAKE_REGS { 0, 0, 0, 0, 0, 0, 0, __KERNEL_DS, 0, 0, (long)__sti, __KERNEL_CS, IENABLE, 0, 0 }
+
+#define MAX_FAKE_DEPTH 200
+struct pt_regs fake_regs[NR_CPUS][MAX_FAKE_DEPTH];
+struct pt_regs *fake_top[NR_CPUS];
+struct pt_regs *next_fake_top(void){
+	int i;
+	struct pt_regs *r = 0;
+#ifdef __SMP__
+	DeclareAndInit(cpu_id);
+#else
+	unsigned int cpu_id = 0;
+#endif
+	for(i=0; i < MAX_FAKE_DEPTH;i++){
+		if(fake_regs[cpu_id][i].orig_eax)continue;
+		else{
+		       	r = &fake_regs[cpu_id][i];
+			r->orig_eax = -1;
+			break;}
+	}
+	if(!r)printk("RTL is astonished to announce out of fake regs\n");
+	return r;
+
+}
+
+void pop_fake(struct pt_regs *r){ r->orig_eax = 0; }
+
+
+
+#ifdef __SMP__
+static inline int fake_local_irq(unsigned int);
+static inline int fake_local_irq(unsigned int cpu_id){
+	struct pt_regs *r;
+	unsigned int pos;
+	rtl_hard_cli();
+	if( !(r= next_fake_top())) {
+		rtl_hard_sti();
+		return 0;
+	}
+	if(RTL_LOCAL.pending){
+		pos = ffz(~RTL_LOCAL.pending);
+		clear_bit(pos,&RTL_LOCAL.pending);
+		r->orig_eax = -1;
+		rtl_hard_sti(); /* yikes */
+		do_local_irq(LOCAL_PND_TO_VECTOR(pos),r);
+		pop_fake(r);
+		return 1;
+	}
+	rtl_hard_sti(); /* yikes */
+	pop_fake(r);
+	return 0; /* didn't find anything to emulate */
+}
+#else
+#define fake_local_irq(x)  0
+#endif
+
+static inline int fake_global_irq(void);
+static inline int fake_global_irq(){
+	int i,pos,active;
+	struct pt_regs *r;
+	rtl_hard_cli();
+	if(!(r= next_fake_top())){
+		rtl_hard_sti();
+		return 0;
+	}
+	rtl_spin_lock(&rtl_global.hard_irq_controller_lock);
+	for(i=0; i < IRQ_ARRAY_SIZE;i++){
+		if((active= (rtl_global.pending[i]&rtl_global.soft_enabled[i])))
+		{
+			pos = ffz(~active);
+			clear_bit(pos,&rtl_global.pending[i]);
+			rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+			rtl_hard_sti(); /* yikes */
+			r->orig_eax = pos_and_index_to_irq(pos,i);
+			do_IRQ(pos_and_index_to_irq(pos,i),r);
+			pop_fake(r);
+			return 1;
+		}
+	}
+	rtl_spin_unlock(&rtl_global.hard_irq_controller_lock);
+	rtl_hard_sti(); /* yikes */
+	pop_fake(r);
+	return 0; /* didn't find anything to emulate */
+}
+
+void __sti(){
+        unsigned int faked_an_interrupt = 0;
+	DeclareAndInit(cpu_id);
+
+	soft_sti();
+	rtl_hard_sti();
+	if(rtl_global.rtl_off) return;
+	do{
+		soft_cli();
+		faked_an_interrupt = fake_global_irq()| fake_local_irq(cpu_id);
+		soft_sti();
+	} while((faked_an_interrupt > 0)
+			|| (test_and_clear_bit(0,&rtl_global.pended_since_sti))
+			|| test_and_clear_bit(RTL_L_SINCE_STI_POS, &RTL_LOCAL.flags));
+		 /* the point of this loop is to make sure that IRQs are not
+	     stranded pending. 
+	     fake_irq may return 0, indicating no irqs pending (nothing to 
+	    fake)  and then a new irq may pend. If so, pended_since_sti will
+	    be true. If an irq occurs after the test for pended_since, it
+	    will simply roll into a second invocation of __sti since we
+	    only do the test with IENABLE and in_sti=0;
+	    Might need a MB, but it should be doable more simply.
+	     */
+
+}
+
+void rtl_init(void)
+{
+	DeclareAndInit(cpu_id);
+#ifdef CONFIG_RTL
+	printk("RTL start");
+	soft_cli();
+	if(test_and_clear_bit(0,&rtl_global.rtl_off)) {
+	  // rtl time stuff is now in a module
+	}
+	printk("ed\n");
+#endif
+	rtl_hard_sti();
+	return;
+}
+
+int rtl_request_global_irq(unsigned int irq, 
+		unsigned int (*handler)(unsigned int, struct pt_regs *))
+{
+	if (!test_and_set_bit(irq,&rtl_global.rtirq)) {
+		rtl_global_handlers[irq].handler =handler;
+/* 		rtl_hard_enable_irq (irq); */
+		return 0;
+	}
+	return -EBUSY;
+}
+
+int rtl_free_global_irq(unsigned int irq )
+{
+	if (!test_bit(irq,&rtl_global.rtirq)) {
+		return -EINVAL;
+	} else {
+		rtl_global_handlers[irq].handler = 0;
+		clear_bit(irq,&rtl_global.rtirq);
+		return 0;
+	}
+}
+
+
+
+#ifdef __SMP__
+/* spinlock_t rtl_lock; */
+int rtl_request_local_irq(int i, unsigned int (*handler)(struct pt_regs *r), unsigned int cpu) {
+	if (i == LOCAL_TIMER_VECTOR) {
+		local_timer_handler[cpu].handler = handler;
+		return 0;
+	}
+	if (i == RTL_RESCHEDULE_VECTOR) {
+		local_resched_handler[cpu].handler = handler;
+		return 0;
+	}
+	printk("rtl_request_local_irq not implemented yet\n");
+	return -EINVAL;
+}
+
+int rtl_free_local_irq(int i, unsigned int cpu){
+	if (i == LOCAL_TIMER_VECTOR) {
+		local_timer_handler[cpu].handler = default_local_timer_handler;
+		return 0;
+	}
+	if (i == RTL_RESCHEDULE_VECTOR) {
+		local_resched_handler[cpu].handler = default_local_resched_handler;
+		return 0;
+	}
+	printk("rtl_free_local_irq not implemented yet\n");
+	return -EINVAL;
+}
+
 #endif
 
Index: linux22/arch/i386/kernel/irq.h
diff -u linux22/arch/i386/kernel/irq.h:1.1.1.1 linux22/arch/i386/kernel/irq.h:1.2
--- linux22/arch/i386/kernel/irq.h:1.1.1.1	Thu Aug 12 22:06:29 1999
+++ linux22/arch/i386/kernel/irq.h	Thu Aug 12 22:12:36 1999
@@ -2,7 +2,19 @@
 #define __irq_h
 
 #include <asm/irq.h>
+#include <linux/rtl.h>
 
+extern void rtl_emulate_enable_irq(unsigned int irq);
+
+/* RTL real time interrupt handlers */
+struct rtl_global_handlers{
+	unsigned int (*handler)(unsigned int irq, struct pt_regs *r);
+}rtl_global_handlers[64];
+
+struct rtl_local_handlers{
+	unsigned int (*handler)(struct pt_regs *r);
+};
+
 /*
  * Interrupt controller descriptor. This is all we need
  * to describe about the low-level hardware.
@@ -14,6 +26,7 @@
 	void (*handle)(unsigned int irq, struct pt_regs * regs);
 	void (*enable)(unsigned int irq);
 	void (*disable)(unsigned int irq);
+	void (*mask_and_ack)(unsigned int irq);
 };
 
 extern struct hw_interrupt_type no_irq_type;
@@ -67,13 +80,27 @@
 #define STOP_CPU_VECTOR		0x40
 #define LOCAL_TIMER_VECTOR	0x41
 #define CALL_FUNCTION_VECTOR	0x50
+#define RTL_RESCHEDULE_VECTOR	0x51
+  
+#define VECTOR_TO_LOCAL_PND(x)  (((x)>>3)|((x)&1))  /* ok, it's stupid */
+#define LOCAL_PND_TO_VECTOR(x)  ((((x)&0xe)<<3)|((x)&1))  /* ok, it's stupid */
+                       /* but  0x30 -> 6
+ 			      0x31 -> 7
+ 			      0x40 -> 8
+ 			      0x41 -> 9
+ 			      0x50 -> A
+ 			      etc
+ 			      only a problem if use more than one bit
+			      in the low order 4 bits or more than 
+			      31 vectors total!
+ 			      */
+  /*
+  * First APIC vector available to drivers: (vectors 0x61-0xfe)
+   */
+#define IRQ0_TRAP_VECTOR	0x61
+  
 
 /*
- * First APIC vector available to drivers: (vectors 0x51-0xfe)
- */
-#define IRQ0_TRAP_VECTOR	0x51
-
-/*
  * This IRQ should never happen, but we print a message nevertheless.
  */
 #define SPURIOUS_APIC_VECTOR	0xff
@@ -185,38 +212,59 @@
  *	SMP has a few special interrupts for IPI messages
  */
 
-#define BUILD_SMP_INTERRUPT(x) \
-asmlinkage void x(void); \
+#define BUILD_COMMON_SMP_IRQ() \
 __asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(x) ":\n\t" \
-	"pushl $-1\n\t" \
+	"\n" __ALIGN_STR"\n" \
+	"common_smp_interrupt:\n\t" \
 	SAVE_ALL \
-	"call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
-	"jmp ret_from_intr\n");
+	"call "SYMBOL_NAME_STR(rtl_smp_intercept)"\n\t"\
+	"testl %eax,%eax;\n\t"\
+	"jz ret_from_intr;\n\t" \
+	"popl %ebx;	\n\t" \
+	"popl %ecx;	\n\t" \
+	"popl %edx;	\n\t" \
+	"popl %esi;	\n\t" \
+	"popl %edi;	\n\t" \
+	"popl %ebp;	\n\t" \
+	"popl %eax;	\n\t" \
+	"popl %ds;	\n\t" \
+	"popl %es;	\n\t" \
+	"addl $4,%esp;	\n\t" \
+	"iret;		\n\t" );
 
-#define BUILD_SMP_TIMER_INTERRUPT(x) \
-asmlinkage void x(struct pt_regs * regs); \
+#define BUILD_SMP_INTERRUPT(vctr,f) \
+asmlinkage void f(void); \
 __asm__( \
 "\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(x) ":\n\t" \
-	"pushl $-1\n\t" \
-	SAVE_ALL \
-	"movl %esp,%eax\n\t" \
-	"pushl %eax\n\t" \
-	"call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
-	"addl $4,%esp\n\t" \
-	"jmp ret_from_intr\n");
+SYMBOL_NAME_STR(f) ":\n\t" \
+	"pushl $"SYMBOL_NAME_STR(vctr)"\n\t" \
+	"jmp common_smp_interrupt");
 
+/* RTL the difference is taken care of in the intercept routine */
+#define BUILD_SMP_TIMER_INTERRUPT(x,y)  BUILD_SMP_INTERRUPT(x,y)
 #endif /* __SMP__ */
 
+/* The restore state part of this better change if
+   SAVE_ALL changes or things will not look good  VY*/
 #define BUILD_COMMON_IRQ() \
 __asm__( \
 	"\n" __ALIGN_STR"\n" \
 	"common_interrupt:\n\t" \
 	SAVE_ALL \
-	"call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
-	"jmp ret_from_intr\n");
+	"call "SYMBOL_NAME_STR(rtl_intercept)"\n\t"\
+	"testl %eax,%eax;\n\t"\
+	"jz ret_from_intr;\n\t" \
+	"popl %ebx;	\n\t" \
+	"popl %ecx;	\n\t" \
+	"popl %edx;	\n\t" \
+	"popl %esi;	\n\t" \
+	"popl %edi;	\n\t" \
+	"popl %ebp;	\n\t" \
+	"popl %eax;	\n\t" \
+	"popl %ds;	\n\t" \
+	"popl %es;	\n\t" \
+	"addl $4,%esp;	\n\t" \
+	"iret;		\n\t" );
 
 /*
  * subtle. orig_eax is used by the signal code to distinct between
Index: linux22/arch/i386/kernel/smp.c
diff -u linux22/arch/i386/kernel/smp.c:1.1.1.2 linux22/arch/i386/kernel/smp.c:1.6
--- linux22/arch/i386/kernel/smp.c:1.1.1.2	Wed Oct 20 23:16:03 1999
+++ linux22/arch/i386/kernel/smp.c	Tue Oct 26 01:29:28 1999
@@ -1581,6 +1581,14 @@
 #endif
 }
 
+
+#ifdef __RTL__
+void rtl_reschedule(unsigned int cpu){
+		send_IPI_single(cpu,RTL_RESCHEDULE_VECTOR);
+}
+#endif
+
+
 /*
  * This is fraught with deadlocks. Probably the situation is not that
  * bad as in the early days of SMP, so we might ease some of the
@@ -1625,7 +1633,7 @@
 		 * Spin waiting for completion
 		 */
 
-		stuck = 50000000;
+		stuck = 250000000;
 		while (smp_invalidate_needed) {
 			/*
 			 * Take care of "crossing" invalidates
@@ -1840,7 +1848,10 @@
 	 * want to be able to accept NMI tlb invalidates
 	 * during this time.
 	 */
+#ifndef __RTL__
 	ack_APIC_irq();
+	/* RTL --  no ack here, ack in intercept */
+#endif
 	smp_local_timer_interrupt(regs);
 }
 
@@ -1851,7 +1862,10 @@
  */
 asmlinkage void smp_reschedule_interrupt(void)
 {
+#ifndef __RTL__
 	ack_APIC_irq();
+	/* RTL --  no ack here, ack in intercept */
+#endif
 }
 
 /*
@@ -1861,9 +1875,9 @@
 {
 	if (test_and_clear_bit(smp_processor_id(), &smp_invalidate_needed))
 		local_flush_tlb();
-
+#ifndef __RTL__
 	ack_APIC_irq();
-
+#endif
 }
 
 static void stop_this_cpu (void)
@@ -1892,7 +1906,9 @@
 	void *info = smp_call_function_data->info;
 	int wait = smp_call_function_data->wait;
 
+#ifndef __RTL__
 	ack_APIC_irq ();
+#endif
 	/*  Notify initiating CPU that I've grabbed the data and am about to
 	    execute the function  */
 	atomic_dec (&smp_call_function_data->unstarted_count);
@@ -2125,8 +2141,8 @@
 	/*
 	 * We ACK the APIC, just in case there is something pending.
 	 */
+	ack_APIC_irq(); /* RTL ok to ack in an initialization routine*/
 
-	ack_APIC_irq ();
 
 	__restore_flags(flags);
 }
Index: linux22/arch/i386/kernel/time.c
diff -u linux22/arch/i386/kernel/time.c:1.1.1.1 linux22/arch/i386/kernel/time.c:1.3
--- linux22/arch/i386/kernel/time.c:1.1.1.1	Thu Aug 12 22:06:29 1999
+++ linux22/arch/i386/kernel/time.c	Mon Oct 25 03:07:40 1999
@@ -223,7 +223,7 @@
 	return count;
 }
 
-static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
 
 #else
 
Index: linux22/fs/proc/array.c
diff -u linux22/fs/proc/array.c:1.1.1.3 linux22/fs/proc/array.c:1.4
--- linux22/fs/proc/array.c:1.1.1.3	Wed Oct 20 23:13:43 1999
+++ linux22/fs/proc/array.c	Wed Oct 20 23:24:41 1999
@@ -75,6 +75,9 @@
 int get_malloc(char * buffer);
 #endif
 
+#ifdef CONFIG_RTL
+extern int get_rtl_status(char *buf);
+#endif
 
 static int open_kcore(struct inode * inode, struct file * filp)
 {
@@ -1383,6 +1386,10 @@
 #ifdef CONFIG_RTC
 		case PROC_RTC:
 			return get_rtc_status(page);
+#endif
+#ifdef CONFIG_RTL
+		case PROC_RTLINUX:
+			return get_rtl_status(page);
 #endif
 #ifdef CONFIG_SGI_DS1286
 		case PROC_RTC:
Index: linux22/fs/proc/root.c
diff -u linux22/fs/proc/root.c:1.1.1.2 linux22/fs/proc/root.c:1.3
--- linux22/fs/proc/root.c:1.1.1.2	Wed Oct 20 23:13:43 1999
+++ linux22/fs/proc/root.c	Wed Oct 20 23:24:41 1999
@@ -633,6 +633,13 @@
 	0, &proc_array_inode_operations
 };
 #endif
+#ifdef CONFIG_RTL
+static struct proc_dir_entry proc_root_rtlinux = {
+		PROC_RTLINUX, 7, "rtlinux",
+		S_IFREG | S_IRUGO, 1, 0, 0,
+	0, &proc_array_inode_operations
+	};
+#endif
 #ifdef CONFIG_SGI_DS1286
 static struct proc_dir_entry proc_root_ds1286 = {
 	PROC_RTC, 3, "rtc",
@@ -686,6 +693,9 @@
 	proc_register(&proc_root, &proc_root_version);
 	proc_register(&proc_root, &proc_root_cpuinfo);
 	proc_register(&proc_root, &proc_root_self);
+#ifdef CONFIG_RTL
+	proc_register(&proc_root, &proc_root_rtlinux);
+#endif
 	proc_net = create_proc_entry("net", S_IFDIR, 0);
 	proc_scsi = create_proc_entry("scsi", S_IFDIR, 0);
 #ifdef CONFIG_SYSCTL
Index: linux22/include/asm-i386/irq.h
diff -u linux22/include/asm-i386/irq.h:1.1.1.1 linux22/include/asm-i386/irq.h:1.2
--- linux22/include/asm-i386/irq.h:1.1.1.1	Thu Aug 12 22:05:36 1999
+++ linux22/include/asm-i386/irq.h	Thu Aug 12 22:12:37 1999
@@ -21,7 +21,13 @@
  * Since vectors 0x00-0x1f are used/reserved for the CPU,
  * the usable vector space is 0x20-0xff (224 vectors)
  */
+
+#ifndef __RTL__
 #define NR_IRQS 224
+#else 
+/* RTL quick hack */
+#define NR_IRQS 64
+#endif
 
 static __inline__ int irq_cannonicalize(int irq)
 {
Index: linux22/include/asm-i386/rtl_sync.h
diff -u /dev/null linux22/include/asm-i386/rtl_sync.h:1.5
--- /dev/null	Thu Nov 25 15:32:16 1999
+++ linux22/include/asm-i386/rtl_sync.h	Thu Oct 21 00:35:56 1999
@@ -0,0 +1,69 @@
+#ifndef __RTL_LINUX_SYNC_H__
+#define __RTL_LINUX_SYNC_H__
+
+#include <linux/rtl_trace.h>
+#include <asm/spinlock.h>
+
+/* DO NOT USE THESE OUTSIDE OF THE RTLINUX CODE!!! */
+/* (c) Victor Yodaiken 1999. */
+
+#ifndef CONFIG_RTL_TRACER
+
+#define rtl_allow_interrupts() __asm__ __volatile__ ("sti": : :"memory")
+#define rtl_stop_interrupts() __asm__ __volatile__ ("cli": : :"memory")
+#define rtl_save_interrupts(x) \
+__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
+#define rtl_restore_interrupts(x) \
+__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
+#define rtl_no_interrupts(x) \
+__asm__ __volatile__("pushfl ; cli;  popl %0": "=g" (x): /* no input */ :"memory")
+/* I wonder if the code above is slower because the cli gives the pushed
+   value a chance to disappear from some forwarding register? VY */
+
+
+#else
+
+#define rtl_allow_interrupts() do { rtl_trace2a(RTL_TRACE_ALLOW_INTERRUPTS, 0); __asm__ __volatile__ ("sti": : :"memory"); } while (0)
+#define rtl_stop_interrupts() do { __asm__ __volatile__ ("cli": : :"memory"); rtl_trace2(RTL_TRACE_STOP_INTERRUPTS, 0); } while (0)
+#define rtl_save_interrupts(x) \
+do { __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory");  rtl_trace2(RTL_TRACE_SAVE_INTERRUPTS, x); } while (0)
+#define rtl_restore_interrupts(x) \
+do { __asm__ __volatile__ ("cli": : :"memory"); rtl_trace2a(RTL_TRACE_RESTORE_INTERRUPTS, x); __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory"); } while (0)
+#define rtl_no_interrupts(x) \
+do { __asm__ __volatile__("pushfl ; cli;  popl %0": "=g" (x): /* no input */ :"memory"); rtl_trace2(RTL_TRACE_NO_INTERRUPTS, x); } while (0)
+
+#endif
+
+#define rtl_hard_savef_and_cli(x) rtl_no_interrupts(x)
+#define rtl_hard_restore_flags(x) rtl_restore_interrupts(x)
+#define rtl_hard_sti() rtl_allow_interrupts()
+#define rtl_hard_cli() rtl_stop_interrupts()
+#define rtl_hard_save_flags(x) rtl_save_interrupts(x)
+
+#ifdef __SMP__
+/*
+#define rtl_spin_lock(x)  { static int z;\
+                    	for(z=0;z<100000000;z++)\
+	                  if(!test_and_set_bit(0,x.lock))break;\
+			  rtl_trace2(RTL_TRACE_SPIN_LOCK, (long ) x); \
+			if(! rtl_global.rtl_off){ \
+                          if(z==100000000) { \
+				conpr("\nRTLBADSpin=");\
+			      	conprn((unsigned int)&z);\
+				panic("badspin");    }}}
+
+			  
+#define rtl_spin_unlock(x)  do { rtl_trace2a(RTL_TRACE_SPIN_UNLOCK, (long) x); clear_bit(0,x.lock); } while (0)
+*/
+
+#define rtl_spin_lock(x) do { spin_lock(x); rtl_trace2(RTL_TRACE_SPIN_LOCK, (long)x); } while (0)
+#define rtl_spin_unlock(x) do { rtl_trace2a(RTL_TRACE_SPIN_UNLOCK, (long) x); spin_unlock(x); } while (0)
+
+#else
+
+#define rtl_spin_lock(x)
+#define rtl_spin_unlock(x)
+
+#endif
+
+#endif
Index: linux22/include/asm-i386/system.h
diff -u linux22/include/asm-i386/system.h:1.1.1.1 linux22/include/asm-i386/system.h:1.2
--- linux22/include/asm-i386/system.h:1.1.1.1	Thu Aug 12 22:05:36 1999
+++ linux22/include/asm-i386/system.h	Thu Aug 12 22:12:37 1999
@@ -174,6 +174,8 @@
 #define wmb()	__asm__ __volatile__ ("": : :"memory")
 
 /* interrupt control.. */
+/* RTL: these are all defined in irq.c for now */
+#if 0 /* ! __RTL__ */
 #define __sti() __asm__ __volatile__ ("sti": : :"memory")
 #define __cli() __asm__ __volatile__ ("cli": : :"memory")
 #define __save_flags(x) \
@@ -181,6 +183,13 @@
 #define __restore_flags(x) \
 __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
 
+#else
+extern void __sti(void);
+extern void __cli(void);
+extern void __restore_flags(unsigned int);
+extern unsigned int __return_flags(void);
+#define __save_flags(x) {x = __return_flags();}
+#endif
 
 #ifdef __SMP__
 
Index: linux22/include/linux/cons.h
diff -u /dev/null linux22/include/linux/cons.h:1.5
--- /dev/null	Thu Nov 25 15:32:20 1999
+++ linux22/include/linux/cons.h	Mon Oct 25 08:38:22 1999
@@ -0,0 +1,94 @@
+#ifndef __RTL_CONS_H__
+#define __RTL_CONS_H__
+/*
+ * debugging routines for RT-Linux
+ *
+ * Copyright (C) Michael Barabanov 1997
+ * Copyright (C) VJY Associates 1999
+ * Released under the terms of the GPL
+ *
+ */
+
+#include <asm/system.h>
+
+extern void conpr(const char * b);
+
+extern int rtl_printf(const char * fmt, ...);
+
+static inline void conprn(const unsigned int hexnum)
+{
+	int i;
+	unsigned int d;
+	unsigned int n = hexnum;
+    	char s[10];
+	s[9] = 0;
+	s[8] = ' ';
+	for (i=7; i>=0; i--) {
+		d = n % 16;
+		if (d < 10) {
+			d += '0';
+		} else {
+			d += 'a' - 10;
+		}
+		s[i] = d; 
+		n = n / 16;
+	}
+    	conpr(s);
+}
+
+static inline void conprd(const unsigned int num)
+{
+	int i;
+	unsigned int d;
+	unsigned int n = num;
+    	char s[12];
+	s[11] = 0;
+	s[10] = ' ';
+	for (i=9; i>=0; i--) {
+		d = n % 10;
+		if (d < 10) {
+			d += '0';
+		} else {
+			d += 'a' - 10;
+		}
+		s[i] = d; 
+		n = n / 10;
+	}
+    	conpr(s);
+}
+
+#define rt_check_cli() { long flags; r_save_flags(flags); \
+	if (flags & 0x200) { \
+		conpr("interrupts are enabled!\n"); \
+	} \
+}
+
+#define CONPRX(a,b)  {conpr(a); conprn((int)(b)); conpr("\n");}
+#define conprll(ll) { conprn((int)((ll) >> 32)); conprn((int) (ll)); }
+#define conprtime(ts) { conprd((ts).tv_sec); conprd((ts).tv_nsec); }
+
+#define PRINTAX \
+	"pushl %%eax\n\t" \
+	"pushl %%ebp\n\t" \
+	"pushl %%edi\n\t" \
+	"pushl %%esi\n\t" \
+	"pushl %%edx\n\t" \
+	"pushl %%ecx\n\t" \
+	"pushl %%ebx\n\t" \
+	"pushl %%eax\n\t" \
+	"call "SYMBOL_NAME_STR(conprn)"\n\t" \
+	"add $4, %%esp\n\t" \
+	"popl %%ebx\n\t \
+	popl %%ecx\n\t \
+	popl %%edx\n\t \
+	popl %%esi\n\t \
+	popl %%edi\n\t \
+	popl %%ebp\n\t \
+	popl %%eax\n\t"
+
+extern inline void conf(void) {
+ int i;
+ for ( i=0; i< 10000000; i++); 
+}
+
+#endif
Index: linux22/include/linux/major.h
diff -u linux22/include/linux/major.h:1.1.1.2 linux22/include/linux/major.h:1.3
--- linux22/include/linux/major.h:1.1.1.2	Wed Sep  1 20:08:29 1999
+++ linux22/include/linux/major.h	Wed Sep  1 20:18:51 1999
@@ -83,6 +83,7 @@
 #define IDE4_MAJOR	56
 #define IDE5_MAJOR	57
 
+#define RTF_MAJOR 150  /* real time fifos RTL */
 #define SCSI_DISK1_MAJOR	65
 #define SCSI_DISK2_MAJOR	66
 #define SCSI_DISK3_MAJOR	67
Index: linux22/include/linux/proc_fs.h
diff -u linux22/include/linux/proc_fs.h:1.1.1.3 linux22/include/linux/proc_fs.h:1.4
--- linux22/include/linux/proc_fs.h:1.1.1.3	Wed Oct 20 23:13:57 1999
+++ linux22/include/linux/proc_fs.h	Wed Oct 20 23:24:41 1999
@@ -53,6 +53,9 @@
 	PROC_SOUND,
 	PROC_MTRR, /* whether enabled or not */
 	PROC_FS
+#ifdef CONFIG_RTL
+	,PROC_RTLINUX
+#endif
 };
 
 enum pid_directory_inos {
Index: linux22/include/linux/rtl.h
diff -u /dev/null linux22/include/linux/rtl.h:1.5
--- /dev/null	Thu Nov 25 15:32:22 1999
+++ linux22/include/linux/rtl.h	Sun Sep 19 15:24:51 1999
@@ -0,0 +1,35 @@
+/* Copyright Victor Yodaiken 1999. 
+   Released under the terms of the GNU Library GPL 
+   */
+   
+#ifndef __rtl_h
+#define __rtl_h
+
+extern void rtl_make_rt_system_active(void); 
+extern unsigned int rtl_rt_system_is_idle(void);
+extern void rtl_make_rt_system_idle(void);
+extern unsigned int rtl_hard_smp_processor_id(void);
+extern void rtl_reschedule(unsigned int);
+
+extern int rtl_get_soft_irq( void (*handler)(int, void *, struct pt_regs *),
+		const char * devname);
+
+extern int rtl_request_global_irq(unsigned int irq, 
+		unsigned int (*handler)(unsigned int, struct pt_regs *));
+extern int rtl_free_global_irq(unsigned int irq); 
+extern void rtl_global_pend_irq(int ix);
+
+/* if you don't say local, you mean global */
+#define rtl_request_irq(x, y) rtl_request_global_irq(x, y)
+#define rtl_free_irq(x) rtl_free_global_irq(x)
+
+#ifdef __SMP__
+int rtl_request_local_irq(int i, unsigned int (*handler)(struct pt_regs *r),
+		unsigned int cpu);
+int rtl_free_local_irq(int i, unsigned int cpu);
+
+extern void rtl_local_pend_vec(int intvec,int cpu_id);
+
+#endif
+
+#endif
Index: linux22/include/linux/rtl_trace.h
diff -u /dev/null linux22/include/linux/rtl_trace.h:1.5
--- /dev/null	Thu Nov 25 15:32:22 1999
+++ linux22/include/linux/rtl_trace.h	Sun Sep 19 18:54:15 1999
@@ -0,0 +1,43 @@
+#ifndef __RTL_TRACE_H__
+#define __RTL_TRACE_H__
+
+/* #undef to leave no trace */
+/* #define CONFIG_RTL_TRACER */
+
+/* event ids */
+enum {  RTL_TRACE_STOP_INTERRUPTS = 1, RTL_TRACE_ALLOW_INTERRUPTS = 2,
+       	RTL_TRACE_SAVE_INTERRUPTS = 4, RTL_TRACE_RESTORE_INTERRUPTS = 8,
+       	RTL_TRACE_NO_INTERRUPTS = 16,
+	RTL_TRACE_SMP_INTERCEPT = 32, RTL_TRACE_SMP_INTERCEPT_EXIT = 64,
+	RTL_TRACE_USER = 128, RTL_TRACE_SPIN_LOCK = 256, RTL_TRACE_SPIN_UNLOCK = 512, RTL_TRACE_INTERCEPT = 1024, RTL_TRACE_INTERCEPT_EXIT = 2048,
+	RTL_TRACE_USER2 = 4096};
+
+#define RTL_TRACE_ALL 0xffffffff
+
+
+#ifdef CONFIG_RTL_TRACER
+extern void (*rtl_trace)(int event_id, long event_data, long eip);
+
+#define rtl_trace2(event_id, event_data) \
+do { \
+	long eip; \
+	__asm__("1: mov $1b, %%eax" : "=a" (eip) : ); \
+	rtl_trace(event_id, event_data, eip); \
+} while (0)
+
+#define rtl_trace2a(event_id, event_data) \
+do { \
+	long eip; \
+	__asm__("mov $1f, %%eax" : "=a" (eip) : ); \
+	rtl_trace(event_id, event_data, eip); \
+	__asm__("1:" : : ); \
+} while (0)
+
+#else
+
+#define rtl_trace(event_id, event_data, eip)
+#define rtl_trace2(event_id, event_data)
+#define rtl_trace2a(event_id, event_data)
+#endif
+
+#endif
Index: linux22/init/main.c
diff -u linux22/init/main.c:1.1.1.2 linux22/init/main.c:1.3
--- linux22/init/main.c:1.1.1.2	Wed Oct 20 23:13:52 1999
+++ linux22/init/main.c	Wed Oct 20 23:24:41 1999
@@ -1143,6 +1143,9 @@
 #endif
 
 extern void initialize_secondary(void);
+#ifdef CONFIG_RTL
+extern void rtl_init(void);
+#endif
 
 /*
  *	Activate the first processor.
@@ -1229,6 +1232,10 @@
 	 *	make syscalls (and thus be locked).
 	 */
 	smp_init();
+#ifdef CONFIG_RTL
+	rtl_init();
+	sti();
+#endif
 	kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	current->need_resched = 1;
  	cpu_idle(NULL);
Index: linux22/kernel/Makefile
diff -u linux22/kernel/Makefile:1.1.1.1 linux22/kernel/Makefile:1.2
--- linux22/kernel/Makefile:1.1.1.1	Thu Aug 12 22:05:32 1999
+++ linux22/kernel/Makefile	Thu Aug 12 22:12:37 1999
@@ -15,6 +15,10 @@
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
 	    sysctl.o acct.o capability.o
 
+ifdef CONFIG_RTL
+O_OBJS += rtl.o
+endif
+
 OX_OBJS  += signal.o
 
 ifeq ($(CONFIG_KMOD),y)
Index: linux22/kernel/ksyms.c
diff -u linux22/kernel/ksyms.c:1.1.1.2 linux22/kernel/ksyms.c:1.7
--- linux22/kernel/ksyms.c:1.1.1.2	Wed Oct 20 23:13:53 1999
+++ linux22/kernel/ksyms.c	Tue Oct 26 01:29:35 1999
@@ -406,5 +406,53 @@
 /* library functions */
 EXPORT_SYMBOL(strnicmp);
 
+#ifdef __RTL__
+/* functions needed for RTL */
+#include <linux/rtl_trace.h>
+
+#ifdef CONFIG_RTL_TRACER
+EXPORT_SYMBOL(rtl_trace);
+#endif
+
+#include <asm/system.h>
+#include <linux/rtl.h>
+EXPORT_SYMBOL(__cli);
+EXPORT_SYMBOL(__sti);
+EXPORT_SYMBOL(__return_flags);
+EXPORT_SYMBOL(__restore_flags);
+
+#ifdef __SMP__
+EXPORT_SYMBOL(smp_found_config);
+#endif
+
+extern int rtl_printf(const char * fmt, ...);
+extern void conpr(const char * b);
+extern void rtl_hard_enable_irq(int ); 
+extern void rtl_hard_disable_irq(int );
+EXPORT_SYMBOL(rtl_printf);
+EXPORT_SYMBOL(conpr);
+EXPORT_SYMBOL(rtl_request_global_irq);
+EXPORT_SYMBOL(rtl_free_global_irq);
+EXPORT_SYMBOL(rtl_global_pend_irq);
+EXPORT_SYMBOL(rtl_get_soft_irq);
+EXPORT_SYMBOL(rtl_hard_enable_irq);
+EXPORT_SYMBOL(rtl_hard_disable_irq);
+#ifdef __SMP__
+EXPORT_SYMBOL(rtl_request_local_irq);
+EXPORT_SYMBOL(rtl_free_local_irq);
+EXPORT_SYMBOL(rtl_local_pend_vec);
+#endif
+
+#include <linux/vt_kern.h>
+EXPORT_SYMBOL(kd_mksound);
+
+EXPORT_SYMBOL(rtl_rt_system_is_idle);
+EXPORT_SYMBOL(rtl_make_rt_system_active); 
+EXPORT_SYMBOL(rtl_make_rt_system_idle);
+#ifdef __SMP__
+EXPORT_SYMBOL(rtl_reschedule);
+#endif
+#endif /* __RTL__ */
+
 /* init task, for moving kthread roots - ought to export a function ?? */
 EXPORT_SYMBOL(init_task_union);
Index: linux22/kernel/rtl.c
diff -u /dev/null linux22/kernel/rtl.c:1.2
--- /dev/null	Thu Nov 25 15:32:24 1999
+++ linux22/kernel/rtl.c	Thu Oct 21 23:03:58 1999
@@ -0,0 +1,77 @@
+
+/* REAL TIME LINUX 
+   Right now this is just for the proc entry
+   
+   (c) Victor Yodaiken August 1998, GPL
+   */
+#include <linux/kernel.h>
+/* #include <linux/rtl_version.h> */
+#include <linux/version.h>
+
+#include <linux/mm.h>
+#include <linux/tty_driver.h>
+#include <linux/smp_lock.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/uaccess.h>
+#include <linux/cons.h>
+#include <linux/console.h>
+#include <asm/spinlock.h>
+#include <asm/rtl_sync.h>
+#include <stdarg.h>
+
+
+int get_rtl_status(char *buf)
+{
+	return(sprintf(buf, "RT-Linux version %s\n", UTS_RELEASE));
+}
+
+
+extern struct console *console_drivers;
+
+void conpr(const char *s)
+{
+	long flags;
+	static spinlock_t rtl_conpr_lock = SPIN_LOCK_UNLOCKED;
+	struct console *c;
+	int len = strlen(s);
+
+	rtl_hard_savef_and_cli(flags);
+	spin_lock(&rtl_conpr_lock);
+
+	c = console_drivers;
+	while(c) {
+		if ((c->flags & CON_ENABLED) && c->write)
+			c->write(c, s, len);
+		c = c->next;
+	}
+	spin_unlock(&rtl_conpr_lock);
+	rtl_hard_restore_flags(flags);
+}
+
+
+int rtl_printf(const char * fmt, ...)
+{
+	static char buf[2048];
+	int flags;
+	int i;
+	va_list args;
+	static spinlock_t rtl_cprintf_lock = SPIN_LOCK_UNLOCKED;
+
+	rtl_hard_savef_and_cli(flags);
+	spin_lock(&rtl_cprintf_lock);
+
+	va_start(args, fmt);
+	i=vsprintf(buf,fmt,args);
+	va_end(args);
+	conpr(buf);
+
+	rtl_hard_cli();
+	spin_unlock(&rtl_cprintf_lock);
+	rtl_hard_restore_flags(flags);
+
+	return i;
+}
+
+
