[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
linux-2.2.16 kernel patch for rtlinux-2.2
attached is an updated kernel patch for rtlinux-2.2
that applies cleanly to a linux-2.2.16 source tree.
also attached is a script that will unpack, patch, build and install a
linux-2.2.16-9mdk-rtl22 kernel.
this has been tested on linux mandrake 7.0 and 7.1 systems
using the linux-2.2.16-9mdk kernel source from the
mandrake 7.1 update RPM kernel-2.2.16-9mdk.i586.rpm.
--
Todd Pfaff \ Email: pfaff at mcmaster dot ca
Computing and Information Services \ Voice: (905) 525-9140 x22920
ABB 132 \ FAX: (905) 528-3773
McMaster University \
Hamilton, Ontario, Canada L8S 4M1 \
#
# kernel patch
# for rtlinux-2.2
# and linux kernel 2.2.16
#
# this has been tested on linux mandrake 7.0 and 7.1 systems
# using the linux-2.2.16-9mdk kernel source from the
# mandrake 7.1 update RPM kernel-2.2.16-9mdk.i586.rpm
#
# you may have to adjust some things for other
# linux-2.2.16 kernel distributions (eg. redhat)
# in particular, the EXTRAVERSION setting in Makefile
# search for EXTRAVERSION in the patch below
#
# Todd Pfaff
# pfaff@mcmaster.ca
# July 6 2000
#
--- linux-2.2.16/include/asm-i386/irq.h.orig Thu May 6 17:02:34 1999
+++ linux-2.2.16/include/asm-i386/irq.h Thu Jul 6 12:45:27 2000
@@ -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)
{
--- linux-2.2.16/include/asm-i386/rtl_sync.h.orig Thu Jul 6 12:45:27 2000
+++ linux-2.2.16/include/asm-i386/rtl_sync.h Thu Jul 6 12:45:27 2000
@@ -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
--- linux-2.2.16/include/asm-i386/system.h.orig Thu Jun 22 20:04:03 2000
+++ linux-2.2.16/include/asm-i386/system.h Thu Jul 6 12:45:27 2000
@@ -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__
--- linux-2.2.16/include/linux/cons.h.orig Thu Jul 6 12:45:27 2000
+++ linux-2.2.16/include/linux/cons.h Thu Jul 6 12:45:27 2000
@@ -0,0 +1,92 @@
+#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);
+
+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
--- linux-2.2.16/include/linux/major.h.orig Thu Jun 22 18:55:05 2000
+++ linux-2.2.16/include/linux/major.h Thu Jul 6 12:45:27 2000
@@ -85,6 +85,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
--- linux-2.2.16/include/linux/proc_fs.h.orig Thu Jun 22 20:04:25 2000
+++ linux-2.2.16/include/linux/proc_fs.h Thu Jul 6 12:45:27 2000
@@ -53,6 +53,9 @@
PROC_SOUND,
PROC_MTRR, /* whether enabled or not */
PROC_FS
+#ifdef CONFIG_RTL
+ ,PROC_RTLINUX
+#endif
};
enum pid_directory_inos {
--- linux-2.2.16/include/linux/rtl.h.orig Thu Jul 6 12:45:27 2000
+++ linux-2.2.16/include/linux/rtl.h Thu Jul 6 12:45:27 2000
@@ -0,0 +1,36 @@
+/* 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);
+extern int rtl_global_ispending_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
--- linux-2.2.16/include/linux/rtl_trace.h.orig Thu Jul 6 12:45:27 2000
+++ linux-2.2.16/include/linux/rtl_trace.h Thu Jul 6 12:45:27 2000
@@ -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
--- linux-2.2.16/arch/i386/kernel/entry.S.orig Wed May 3 20:16:31 2000
+++ linux-2.2.16/arch/i386/kernel/entry.S Thu Jul 6 12:45:27 2000
@@ -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
--- linux-2.2.16/arch/i386/kernel/i386_ksyms.c.orig Tue Oct 26 20:53:39 1999
+++ linux-2.2.16/arch/i386/kernel/i386_ksyms.c Thu Jul 6 12:45:27 2000
@@ -116,6 +116,13 @@
EXPORT_SYMBOL(mca_is_adapter_used);
#endif
+/* #ifndef CONFIG_X86_TSC */
+unsigned long (*do_gettimeoffset)(void);
+unsigned int use_tsc;
+EXPORT_SYMBOL(do_gettimeoffset);
+EXPORT_SYMBOL(use_tsc);
+/* #endif */
+
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
--- linux-2.2.16/arch/i386/kernel/io_apic.c.orig Wed Jun 7 17:26:42 2000
+++ linux-2.2.16/arch/i386/kernel/io_apic.c Thu Jul 6 12:45:27 2000
@@ -1040,7 +1040,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);
}
@@ -1069,7 +1073,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;
@@ -1106,9 +1112,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;
@@ -1124,7 +1149,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);
/*
@@ -1138,7 +1165,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 */
@@ -1150,7 +1179,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);
}
@@ -1170,6 +1203,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 = {
@@ -1179,6 +1215,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)
--- linux-2.2.16/arch/i386/kernel/irq.c.orig Wed Jun 7 17:26:42 2000
+++ linux-2.2.16/arch/i386/kernel/irq.c Thu Jul 6 12:45:27 2000
@@ -39,8 +39,135 @@
#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);}
+int rtl_global_ispending_irq(int ix) { return global_is_pending_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 +238,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 +282,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 +372,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 +396,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 +409,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 +477,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 +492,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 +510,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
};
@@ -761,7 +922,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);
}
@@ -784,12 +945,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--;
@@ -799,6 +961,7 @@
__builtin_return_address(0));
}
spin_unlock_irqrestore(&irq_controller_lock, flags);
+ if(is_soft_sti())__sti();
}
/*
@@ -806,23 +969,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, ®s);
+ irq_desc[irq].handler->handle(irq, regs);
/*
* This should be conditional: we should really get
@@ -884,12 +1039,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,
@@ -952,7 +1127,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;
}
@@ -997,7 +1172,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);
@@ -1021,7 +1196,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);
@@ -1051,7 +1227,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);
@@ -1131,6 +1307,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");
@@ -1160,3 +1339,531 @@
}
#endif
+#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 */
+
+/* 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,®s);
+ soft_sti();
+ return 0;
+ }
+
+ switch (vector) {
+ case RTL_RESCHEDULE_VECTOR:
+ local_resched_handler[cpu_id].handler(®s);
+ rtl_trace(RTL_TRACE_SMP_INTERCEPT_EXIT, vector, regs.eip);
+ return 1;
+ case LOCAL_TIMER_VECTOR:
+ local_timer_handler[cpu_id].handler(®s);
+ 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,®s);
+ 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,®s);
+ 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,®s);
+ __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
+
--- linux-2.2.16/arch/i386/kernel/irq.h.orig Thu Jun 22 20:06:08 2000
+++ linux-2.2.16/arch/i386/kernel/irq.h Thu Jul 6 12:45:27 2000
@@ -2,6 +2,18 @@
#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
@@ -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,11 +80,25 @@
#define STOP_CPU_VECTOR 0x40
#define LOCAL_TIMER_VECTOR 0x41
#define CALL_FUNCTION_VECTOR 0x50
-
-/*
- * First APIC vector available to drivers: (vectors 0x51-0xfe)
- */
-#define IRQ0_TRAP_VECTOR 0x51
+#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
+
/*
* This IRQ should never happen, but we print a message nevertheless.
@@ -190,38 +217,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
--- linux-2.2.16/arch/i386/kernel/smp.c.orig Thu Jun 22 18:55:03 2000
+++ linux-2.2.16/arch/i386/kernel/smp.c Thu Jul 6 12:45:27 2000
@@ -1804,6 +1804,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
@@ -1853,7 +1861,7 @@
* guessed from the TSC calibration.
*/
- stuck = 50000000 + cpu_data[cpu].loops_per_sec/2;
+ stuck = 250000000 + cpu_data[cpu].loops_per_sec/2;
while (smp_invalidate_needed) {
/*
* Take care of "crossing" invalidates
@@ -2068,7 +2076,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);
}
@@ -2079,7 +2090,10 @@
*/
asmlinkage void smp_reschedule_interrupt(void)
{
+#ifndef __RTL__
ack_APIC_irq();
+ /* RTL -- no ack here, ack in intercept */
+#endif
}
/*
@@ -2089,9 +2103,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)
@@ -2120,7 +2134,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);
@@ -2353,8 +2369,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);
}
--- linux-2.2.16/arch/i386/kernel/time.c.orig Wed Jun 7 17:26:42 2000
+++ linux-2.2.16/arch/i386/kernel/time.c Thu Jul 6 12:45:27 2000
@@ -110,7 +110,7 @@
#define TICK_SIZE tick
-#ifndef CONFIG_X86_TSC
+/* #ifndef CONFIG_X86_TSC */
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
@@ -223,13 +223,13 @@
return count;
}
-static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
-#else
+/* #else */
-#define do_gettimeoffset() do_fast_gettimeoffset()
+/* #define do_gettimeoffset() do_fast_gettimeoffset() */
-#endif
+/* #endif */
/*
* This version of gettimeofday has microsecond resolution
@@ -409,7 +409,7 @@
#endif
}
-static int use_tsc = 0;
+int use_tsc = 0;
/*
* This is the same as the above, except we _also_ save the current
--- linux-2.2.16/arch/i386/config.in.orig Thu Jun 22 19:14:17 2000
+++ linux-2.2.16/arch/i386/config.in Thu Jul 6 12:45:27 2000
@@ -2,7 +2,9 @@
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/config-language.txt.
#
-mainmenu_name "Linux Kernel Configuration"
+mainmenu_name "RTLinux Kernel Configuration"
+#RTLinux is mandatory.
+define_bool CONFIG_RTL y
mainmenu_option next_comment
comment 'Code maturity level options'
--- linux-2.2.16/arch/i386/defconfig.orig Thu Jun 22 20:28:51 2000
+++ linux-2.2.16/arch/i386/defconfig Thu Jul 6 12:45:27 2000
@@ -24,6 +24,7 @@
CONFIG_MATH_EMULATION=y
CONFIG_MTRR=y
# CONFIG_SMP is not set
+CONFIG_RTL=y
#
# Loadable module support
--- linux-2.2.16/drivers/block/ide.c.orig Thu Jun 22 18:55:07 2000
+++ linux-2.2.16/drivers/block/ide.c Thu Jul 6 12:45:27 2000
@@ -188,6 +188,7 @@
*/
static unsigned long read_timer(void)
{
+#ifndef CONFIG_RTL
unsigned long t, flags;
int i;
@@ -199,6 +200,9 @@
i |= inb(0x40) << 8;
__restore_flags(flags); /* local CPU only */
return (t - i);
+#else
+ return 0;
+#endif
}
#endif /* DISK_RECOVERY_TIME */
--- linux-2.2.16/fs/proc/array.c.orig Thu Jun 22 19:14:17 2000
+++ linux-2.2.16/fs/proc/array.c Thu Jul 6 12:45:27 2000
@@ -77,6 +77,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)
{
@@ -1445,6 +1448,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:
--- linux-2.2.16/fs/proc/root.c.orig Thu Jun 22 19:14:17 2000
+++ linux-2.2.16/fs/proc/root.c Thu Jul 6 12:45:27 2000
@@ -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
--- linux-2.2.16/init/main.c.orig Thu Jun 22 18:55:05 2000
+++ linux-2.2.16/init/main.c Thu Jul 6 12:45:27 2000
@@ -1359,6 +1359,9 @@
#endif
extern void initialize_secondary(void);
+#ifdef CONFIG_RTL
+extern void rtl_init(void);
+#endif
/*
* Activate the first processor.
@@ -1450,6 +1453,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);
--- linux-2.2.16/kernel/Makefile.orig Wed May 6 14:01:46 1998
+++ linux-2.2.16/kernel/Makefile Thu Jul 6 12:45:27 2000
@@ -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)
--- linux-2.2.16/kernel/ksyms.c.orig Thu Jun 22 18:55:10 2000
+++ linux-2.2.16/kernel/ksyms.c Thu Jul 6 12:45:27 2000
@@ -453,6 +453,54 @@
/* 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 void conpr(const char * b);
+extern void rtl_hard_enable_irq(int );
+extern void rtl_hard_disable_irq(int );
+EXPORT_SYMBOL(conpr);
+EXPORT_SYMBOL(rtl_request_global_irq);
+EXPORT_SYMBOL(rtl_free_global_irq);
+EXPORT_SYMBOL(rtl_global_pend_irq);
+EXPORT_SYMBOL(rtl_global_ispending_irq);
+EXPORT_SYMBOL(tick);
+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);
--- linux-2.2.16/kernel/rtl.c.orig Thu Jul 6 12:45:27 2000
+++ linux-2.2.16/kernel/rtl.c Thu Jul 6 12:45:27 2000
@@ -0,0 +1,52 @@
+
+/* 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);
+}
+
--- linux-2.2.16/Makefile.orig Thu Jun 22 20:28:51 2000
+++ linux-2.2.16/Makefile Thu Jul 6 12:45:27 2000
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 2
SUBLEVEL = 16
-EXTRAVERSION = -9mdk
+EXTRAVERSION = -9mdk-rtl22
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
#
#!/bin/sh
#
# build rtl-2.2 with linux-2.2.16-9mdk kernel source
#
# this has been tested on linux mandrake 7.0 and 7.1 systems
# using the linux-2.2.16-9mdk kernel source from the
# mandrake 7.1 update RPM kernel-2.2.16-9mdk.i586.rpm.
#
# Todd Pfaff
# pfaff@mcmaster.ca
# July 6 2000
#
# set $d to the path where you keep
# rtlinux-2.2.tar.gz and the kernel patch
d=/net/msl/usr/local/src/rtl/2.2
#
cd /usr/src
#
# clean out any old rtlinux-2.2 source
#
/bin/rm -rf rtlinux-2.2
tar zxf $d/rtlinux-2.2.tar.gz
#
# i'm assuming we have a virgin linux-2.2.16 source tree here
# if not, adjust as necessary
#
find linux-2.2.16 | cpio -pdm rtlinux-2.2
cd rtlinux-2.2/linux-2.2.16
patch -p1 < $d/kernel_patch-rtl22-linux-2.2.16-9mdk
#
# we can just use the default kernel config
# if we don't need to modify anything
#
cp -p arch/i386/defconfig .config
make oldconfig
#
# otherwise, run either xconfig or menuconfig
# but make sure you exit and save the configuration
# whether you make changes or not
# this is necessary for the build to succeed
#
#make xconfig
#make menuconfig
make dep
make bzImage
make modules
make modules_install
cp -p arch/i386/boot/bzImage /boot/vmlinuz-2.2.16-9mdk-rtl22
cp -p System.map /boot/System.map-2.2.16-9mdk-rtl22
#
# you may have to edit lilo.conf to add a new entry for
# vmlinuz-2.2.16-9mdk-rtl22
# of course, you should only have to do this once
#
#vi /etc/lilo.conf
#
# and then run lilo to update the boot files
#
#lilo
#
#reboot