You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
982 lines
29 KiB
982 lines
29 KiB
diff -Naur linux-2.4.20/Documentation/Configure.help linux-2.4.20-rtai/Documentation/Configure.help |
|
--- linux-2.4.20/Documentation/Configure.help Fri Nov 29 19:01:31 2002 |
|
+++ linux-2.4.20-rtai/Documentation/Configure.help Mon Dec 2 16:11:55 2002 |
|
@@ -254,6 +254,13 @@ |
|
You will need a new lynxer.elf file to flash your firmware with - send |
|
email to Martin.Bligh@us.ibm.com |
|
|
|
+Real-Time Harware Abstraction |
|
+CONFIG_RTHAL |
|
+ The Real-Time Hardware Abstraction Layer (RTHAL) is used by |
|
+ the Real-Time Application Interface (RTAI) to provide a |
|
+ hard real-time environment as part of Linux. This feature |
|
+ cannot be turned off, so say Y. |
|
+ |
|
Support for IBM Summit (EXA) systems |
|
CONFIG_X86_SUMMIT |
|
This option is needed for IBM systems that use the Summit/EXA chipset. |
|
diff -Naur linux-2.4.20/arch/i386/config.in linux-2.4.20-rtai/arch/i386/config.in |
|
--- linux-2.4.20/arch/i386/config.in Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/config.in Mon Dec 2 16:11:55 2002 |
|
@@ -256,6 +256,8 @@ |
|
if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then |
|
define_bool CONFIG_HAVE_DEC_LOCK y |
|
fi |
|
+comment 'CONFIG_RTHAL must be yes' |
|
+bool 'Real-Time Hardware Abstraction Layer' CONFIG_RTHAL |
|
endmenu |
|
|
|
mainmenu_option next_comment |
|
diff -Naur linux-2.4.20/arch/i386/defconfig linux-2.4.20-rtai/arch/i386/defconfig |
|
--- linux-2.4.20/arch/i386/defconfig Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/defconfig Mon Dec 2 16:11:55 2002 |
|
@@ -66,6 +66,7 @@ |
|
# CONFIG_MULTIQUAD is not set |
|
CONFIG_HAVE_DEC_LOCK=y |
|
CONFIG_NR_CPUS=32 |
|
+CONFIG_RTHAL=y |
|
|
|
# |
|
# General setup |
|
diff -Naur linux-2.4.20/arch/i386/kernel/entry.S linux-2.4.20-rtai/arch/i386/kernel/entry.S |
|
--- linux-2.4.20/arch/i386/kernel/entry.S Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/entry.S Mon Dec 2 16:11:55 2002 |
|
@@ -184,6 +184,7 @@ |
|
|
|
|
|
ENTRY(ret_from_fork) |
|
+ sti |
|
pushl %ebx |
|
call SYMBOL_NAME(schedule_tail) |
|
addl $4, %esp |
|
@@ -210,17 +211,20 @@ |
|
call *SYMBOL_NAME(sys_call_table)(,%eax,4) |
|
movl %eax,EAX(%esp) # save the return value |
|
ENTRY(ret_from_sys_call) |
|
- cli # need_resched and signals atomic test |
|
+ call *(SYMBOL_NAME(rthal) + 12) # cli |
|
cmpl $0,need_resched(%ebx) |
|
jne reschedule |
|
cmpl $0,sigpending(%ebx) |
|
jne signal_return |
|
+ sti |
|
+ call *(SYMBOL_NAME(rthal) + 16) # sti |
|
restore_all: |
|
RESTORE_ALL |
|
|
|
ALIGN |
|
signal_return: |
|
- sti # we can get here from an interrupt handler |
|
+ sti # we can get here from an interrupt handler |
|
+ call *(SYMBOL_NAME(rthal) + 16) # sti |
|
testl $(VM_MASK),EFLAGS(%esp) |
|
movl %esp,%eax |
|
jne v86_signal_return |
|
diff -Naur linux-2.4.20/arch/i386/kernel/i386_ksyms.c linux-2.4.20-rtai/arch/i386/kernel/i386_ksyms.c |
|
--- linux-2.4.20/arch/i386/kernel/i386_ksyms.c Sat Aug 3 02:39:42 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/i386_ksyms.c Mon Dec 2 16:11:55 2002 |
|
@@ -32,6 +32,18 @@ |
|
extern void dump_thread(struct pt_regs *, struct user *); |
|
extern spinlock_t rtc_lock; |
|
|
|
+EXPORT_SYMBOL_NOVERS(rthal); |
|
+ |
|
+#ifdef CONFIG_VT |
|
+ #include <linux/vt_kern.h> |
|
+ EXPORT_SYMBOL(kd_mksound); |
|
+#endif |
|
+ |
|
+#include <linux/console.h> |
|
+EXPORT_SYMBOL(console_drivers); |
|
+extern unsigned long cpu_khz; |
|
+EXPORT_SYMBOL(cpu_khz); |
|
+ |
|
#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) |
|
extern void machine_real_restart(unsigned char *, int); |
|
EXPORT_SYMBOL(machine_real_restart); |
|
@@ -172,6 +184,13 @@ |
|
|
|
#ifdef CONFIG_HAVE_DEC_LOCK |
|
EXPORT_SYMBOL(atomic_dec_and_lock); |
|
+#endif |
|
+ |
|
+#ifdef CONFIG_X86_REMOTE_DEBUG |
|
+#include <linux/gdb.h> |
|
+EXPORT_SYMBOL(linux_debug_hook); |
|
+EXPORT_SYMBOL(gdb_irq); |
|
+EXPORT_SYMBOL(gdb_interrupt); |
|
#endif |
|
|
|
extern int is_sony_vaio_laptop; |
|
diff -Naur linux-2.4.20/arch/i386/kernel/i8259.c linux-2.4.20-rtai/arch/i386/kernel/i8259.c |
|
--- linux-2.4.20/arch/i386/kernel/i8259.c Tue Sep 18 08:03:09 2001 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/i8259.c Mon Dec 2 16:11:55 2002 |
|
@@ -290,12 +290,12 @@ |
|
|
|
handle_real_irq: |
|
if (irq & 8) { |
|
- inb(0xA1); /* DUMMY - (do we need this?) */ |
|
+// inb(0xA1); /* DUMMY - (do we need this?) */ |
|
outb(cached_A1,0xA1); |
|
outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ |
|
outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ |
|
} else { |
|
- inb(0x21); /* DUMMY - (do we need this?) */ |
|
+// inb(0x21); /* DUMMY - (do we need this?) */ |
|
outb(cached_21,0x21); |
|
outb(0x60+irq,0x20); /* 'Specific EOI' to master */ |
|
} |
|
@@ -508,3 +508,17 @@ |
|
if (boot_cpu_data.hard_math && !cpu_has_fpu) |
|
setup_irq(13, &irq13); |
|
} |
|
+ |
|
+void ack_8259_irq(unsigned int irq) |
|
+{ |
|
+ spin_lock(&i8259A_lock); |
|
+ if (irq & 8) { |
|
+ outb(0x62,0x20); |
|
+ outb(0x20,0xA0); |
|
+ } else { |
|
+ outb(0x20,0x20); |
|
+ } |
|
+ spin_unlock(&i8259A_lock); |
|
+ return; |
|
+} |
|
+ |
|
diff -Naur linux-2.4.20/arch/i386/kernel/io_apic.c linux-2.4.20-rtai/arch/i386/kernel/io_apic.c |
|
--- linux-2.4.20/arch/i386/kernel/io_apic.c Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/io_apic.c Mon Dec 2 16:11:55 2002 |
|
@@ -38,7 +38,7 @@ |
|
|
|
#undef APIC_LOCKUP_DEBUG |
|
|
|
-#define APIC_LOCKUP_DEBUG |
|
+//#define APIC_LOCKUP_DEBUG |
|
|
|
static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED; |
|
|
|
@@ -1282,11 +1282,10 @@ |
|
#define enable_level_ioapic_irq unmask_IO_APIC_irq |
|
#define disable_level_ioapic_irq mask_IO_APIC_irq |
|
|
|
+static unsigned long strange_level; |
|
+ |
|
static void end_level_ioapic_irq (unsigned int irq) |
|
{ |
|
- unsigned long v; |
|
- int i; |
|
- |
|
/* |
|
* It appears there is an erratum which affects at least version 0x11 |
|
* of I/O APIC (that's the 82093AA and cores integrated into various |
|
@@ -1306,12 +1305,8 @@ |
|
* operation to prevent an edge-triggered interrupt escaping meanwhile. |
|
* The idea is from Manfred Spraul. --macro |
|
*/ |
|
- i = IO_APIC_VECTOR(irq); |
|
- v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1)); |
|
- |
|
- ack_APIC_irq(); |
|
|
|
- if (!(v & (1 << (i & 0x1f)))) { |
|
+ if (test_and_clear_bit(irq, &strange_level)) { |
|
#ifdef APIC_LOCKUP_DEBUG |
|
struct irq_pin_list *entry; |
|
#endif |
|
@@ -1320,7 +1315,6 @@ |
|
atomic_inc(&irq_mis_count); |
|
#endif |
|
spin_lock(&ioapic_lock); |
|
- __mask_and_edge_IO_APIC_irq(irq); |
|
#ifdef APIC_LOCKUP_DEBUG |
|
for (entry = irq_2_pin + irq;;) { |
|
unsigned int reg; |
|
@@ -1338,10 +1332,30 @@ |
|
#endif |
|
__unmask_and_level_IO_APIC_irq(irq); |
|
spin_unlock(&ioapic_lock); |
|
+ } else { |
|
+ spin_lock(&ioapic_lock); |
|
+ __unmask_IO_APIC_irq(irq); |
|
+ spin_unlock(&ioapic_lock); |
|
} |
|
} |
|
|
|
-static void mask_and_ack_level_ioapic_irq (unsigned int irq) { /* nothing */ } |
|
+static void mask_and_ack_level_ioapic_irq (unsigned int irq) |
|
+{ |
|
+ unsigned long i; |
|
+ |
|
+ i = IO_APIC_VECTOR(irq); |
|
+ if (!(apic_read(APIC_TMR + ((i & ~0x1f) >> 1)) & (1 << (i & 0x1f)))) { |
|
+ test_and_set_bit(irq, &strange_level); |
|
+ spin_lock(&ioapic_lock); |
|
+ __mask_and_edge_IO_APIC_irq(irq); |
|
+ spin_unlock(&ioapic_lock); |
|
+ } else { |
|
+ spin_lock(&ioapic_lock); |
|
+ __mask_IO_APIC_irq(irq); |
|
+ spin_unlock(&ioapic_lock); |
|
+ } |
|
+ ack_APIC_irq(); |
|
+} |
|
|
|
#ifndef CONFIG_SMP |
|
|
|
diff -Naur linux-2.4.20/arch/i386/kernel/irq.c linux-2.4.20-rtai/arch/i386/kernel/irq.c |
|
--- linux-2.4.20/arch/i386/kernel/irq.c Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/irq.c Mon Dec 2 16:11:55 2002 |
|
@@ -1212,3 +1212,71 @@ |
|
register_irq_proc(i); |
|
} |
|
|
|
+static void linux_cli(void) |
|
+{ |
|
+ hard_cli(); |
|
+} |
|
+ |
|
+static void linux_sti(void) |
|
+{ |
|
+ hard_sti(); |
|
+} |
|
+ |
|
+static unsigned int linux_save_flags(void) |
|
+{ |
|
+ int flags; |
|
+ hard_save_flags(flags); |
|
+ return flags; |
|
+} |
|
+ |
|
+static void linux_restore_flags(unsigned int flags) |
|
+{ |
|
+ hard_restore_flags(flags); |
|
+} |
|
+ |
|
+static unsigned int linux_save_flags_and_cli(void) |
|
+{ |
|
+ int flags; |
|
+ hard_save_flags_and_cli(flags); |
|
+ return flags; |
|
+} |
|
+ |
|
+#include <asm/mmu_context.h> |
|
+ |
|
+#ifndef CONFIG_X86_IO_APIC |
|
+int irq_vector[]; |
|
+#endif |
|
+#ifndef CONFIG_SMP |
|
+void smp_invalidate_interrupt(void) { } |
|
+static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; |
|
+static volatile int physical_apicid_2_cpu[1]; |
|
+#endif |
|
+ |
|
+extern void *ret_from_intr; |
|
+extern struct desc_struct idt_table[]; |
|
+extern void ack_8259_irq(unsigned int); |
|
+extern int idle_weight; |
|
+extern void smp_invalidate_interrupt(void); |
|
+extern void switch_mem(struct task_struct *, struct task_struct *, int); |
|
+extern volatile int physical_apicid_2_cpu[]; |
|
+ |
|
+struct rt_hal rthal = { |
|
+ ret_from_intr: &ret_from_intr, |
|
+ __switch_to: __switch_to, |
|
+ idt_table: idt_table, |
|
+ disint: linux_cli, |
|
+ enint: linux_sti, |
|
+ getflags: linux_save_flags, |
|
+ setflags: linux_restore_flags, |
|
+ getflags_and_cli: linux_save_flags_and_cli, |
|
+ irq_desc: irq_desc, |
|
+ irq_vector: irq_vector, |
|
+ irq_affinity: irq_affinity, |
|
+ smp_invalidate_interrupt: smp_invalidate_interrupt, |
|
+ ack_8259_irq: ack_8259_irq, |
|
+ idle_weight: &idle_weight, |
|
+ lxrt_global_cli: NULL, |
|
+ switch_mem: switch_mem, |
|
+ init_tasks: init_tasks, |
|
+ apicmap: physical_apicid_2_cpu, |
|
+}; |
|
diff -Naur linux-2.4.20/arch/i386/kernel/smp.c linux-2.4.20-rtai/arch/i386/kernel/smp.c |
|
--- linux-2.4.20/arch/i386/kernel/smp.c Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/smp.c Mon Dec 2 16:11:55 2002 |
|
@@ -160,8 +160,7 @@ |
|
unsigned long cfg; |
|
unsigned long flags; |
|
|
|
- __save_flags(flags); |
|
- __cli(); |
|
+ hard_save_flags_and_cli(flags); |
|
|
|
|
|
/* |
|
@@ -185,7 +184,7 @@ |
|
*/ |
|
apic_write_around(APIC_ICR, cfg); |
|
|
|
- __restore_flags(flags); |
|
+ hard_restore_flags(flags); |
|
} |
|
|
|
static inline void send_IPI_mask_sequence(int mask, int vector) |
|
diff -Naur linux-2.4.20/arch/i386/kernel/time.c linux-2.4.20-rtai/arch/i386/kernel/time.c |
|
--- linux-2.4.20/arch/i386/kernel/time.c Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/kernel/time.c Mon Dec 2 16:11:55 2002 |
|
@@ -673,6 +673,7 @@ |
|
|
|
rdtscl(last_tsc_low); |
|
|
|
+#if 0 |
|
spin_lock(&i8253_lock); |
|
outb_p(0x00, 0x43); /* latch the count ASAP */ |
|
|
|
@@ -704,6 +705,7 @@ |
|
|
|
count = ((LATCH-1) - count) * TICK_SIZE; |
|
delay_at_last_interrupt = (count + LATCH/2) / LATCH; |
|
+#endif |
|
} |
|
|
|
do_timer_interrupt(irq, NULL, regs); |
|
diff -Naur linux-2.4.20/arch/i386/mm/fault.c linux-2.4.20-rtai/arch/i386/mm/fault.c |
|
--- linux-2.4.20/arch/i386/mm/fault.c Fri Nov 29 19:01:34 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/mm/fault.c Mon Dec 2 16:11:55 2002 |
|
@@ -153,7 +153,7 @@ |
|
|
|
/* It's safe to allow irq's after cr2 has been saved */ |
|
if (regs->eflags & X86_EFLAGS_IF) |
|
- local_irq_enable(); |
|
+ hard_sti(); |
|
|
|
tsk = current; |
|
|
|
diff -Naur linux-2.4.20/arch/i386/mm/ioremap.c linux-2.4.20-rtai/arch/i386/mm/ioremap.c |
|
--- linux-2.4.20/arch/i386/mm/ioremap.c Sat Aug 3 02:39:42 2002 |
|
+++ linux-2.4.20-rtai/arch/i386/mm/ioremap.c Mon Dec 2 16:11:55 2002 |
|
@@ -81,6 +81,7 @@ |
|
if (remap_area_pmd(pmd, address, end - address, |
|
phys_addr + address, flags)) |
|
break; |
|
+ set_pgdir(address, *dir); |
|
error = 0; |
|
address = (address + PGDIR_SIZE) & PGDIR_MASK; |
|
dir++; |
|
diff -Naur linux-2.4.20/arch/ppc/config.in linux-2.4.20-rtai/arch/ppc/config.in |
|
--- linux-2.4.20/arch/ppc/config.in Fri Nov 29 19:01:45 2002 |
|
+++ linux-2.4.20-rtai/arch/ppc/config.in Mon Dec 2 16:11:55 2002 |
|
@@ -125,6 +125,9 @@ |
|
bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS |
|
fi |
|
|
|
+#bool 'Real-Time Hardware Abstraction Layer' CONFIG_RTHAL |
|
+define_bool CONFIG_RTHAL y |
|
+ |
|
if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then |
|
bool 'AltiVec Support' CONFIG_ALTIVEC |
|
bool 'Thermal Management Support' CONFIG_TAU |
|
diff -Naur linux-2.4.20/arch/ppc/kernel/entry.S linux-2.4.20-rtai/arch/ppc/kernel/entry.S |
|
--- linux-2.4.20/arch/ppc/kernel/entry.S Fri Nov 29 19:01:45 2002 |
|
+++ linux-2.4.20-rtai/arch/ppc/kernel/entry.S Mon Dec 2 16:11:55 2002 |
|
@@ -291,6 +291,7 @@ |
|
bl do_signal |
|
.globl do_signal_ret |
|
do_signal_ret: |
|
+ bl do_soft_sti |
|
.globl ret_to_user_hook |
|
ret_to_user_hook: |
|
nop |
|
diff -Naur linux-2.4.20/arch/ppc/kernel/irq.c linux-2.4.20-rtai/arch/ppc/kernel/irq.c |
|
--- linux-2.4.20/arch/ppc/kernel/irq.c Fri Nov 29 19:01:45 2002 |
|
+++ linux-2.4.20-rtai/arch/ppc/kernel/irq.c Mon Dec 2 16:11:55 2002 |
|
@@ -510,6 +510,17 @@ |
|
spin_unlock(&desc->lock); |
|
} |
|
|
|
+void do_soft_cli(void) |
|
+{ |
|
+} |
|
+ |
|
+void (*rtai_soft_sti)(void); |
|
+ |
|
+void do_soft_sti(void) |
|
+{ |
|
+ if(rtai_soft_sti)rtai_soft_sti(); |
|
+} |
|
+ |
|
int do_IRQ(struct pt_regs *regs) |
|
{ |
|
int cpu = smp_processor_id(); |
|
diff -Naur linux-2.4.20/arch/ppc/kernel/traps.c linux-2.4.20-rtai/arch/ppc/kernel/traps.c |
|
--- linux-2.4.20/arch/ppc/kernel/traps.c Sat Nov 3 02:43:54 2001 |
|
+++ linux-2.4.20-rtai/arch/ppc/kernel/traps.c Mon Dec 2 16:11:55 2002 |
|
@@ -320,9 +320,15 @@ |
|
return retval; |
|
} |
|
|
|
+int (*rtai_srq_bckdr)(struct pt_regs *regs) = NULL; |
|
+ |
|
void |
|
ProgramCheckException(struct pt_regs *regs) |
|
{ |
|
+ if (rtai_srq_bckdr && !rtai_srq_bckdr(regs)) { |
|
+ return; |
|
+ } |
|
+{ |
|
unsigned int reason = get_reason(regs); |
|
extern int do_mathemu(struct pt_regs *regs); |
|
|
|
@@ -378,6 +384,7 @@ |
|
} |
|
|
|
_exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
|
+} |
|
} |
|
|
|
void |
|
diff -Naur linux-2.4.20/arch/ppc/kernel/ppc_ksyms.c linux-2.4.20-rtai/arch/ppc/kernel/ppc_ksyms.c |
|
--- linux-2.4.20/arch/ppc/kernel/ppc_ksyms.c Fri Nov 29 19:01:46 2002 |
|
+++ linux-2.4.20-rtai/arch/ppc/kernel/ppc_ksyms.c Mon Dec 2 16:11:55 2002 |
|
@@ -220,6 +220,12 @@ |
|
EXPORT_SYMBOL(synchronize_irq); |
|
#endif |
|
|
|
+extern int (*rtai_srq_bckdr)(struct pt_regs *); |
|
+EXPORT_SYMBOL(rtai_srq_bckdr); |
|
+ |
|
+extern void (*rtai_soft_sti)(void); |
|
+EXPORT_SYMBOL(rtai_soft_sti); |
|
+ |
|
EXPORT_SYMBOL(ppc_md); |
|
|
|
#ifdef CONFIG_ADB |
|
diff -Naur linux-2.4.20/include/asm-i386/hw_irq.h linux-2.4.20-rtai/include/asm-i386/hw_irq.h |
|
--- linux-2.4.20/include/asm-i386/hw_irq.h Thu Nov 22 20:46:18 2001 |
|
+++ linux-2.4.20-rtai/include/asm-i386/hw_irq.h Mon Dec 2 16:16:00 2002 |
|
@@ -37,18 +37,31 @@ |
|
* |
|
* Vectors 0xf0-0xfa are free (reserved for future Linux use). |
|
*/ |
|
+#ifdef CONFIG_RTHAL |
|
+/* the standard definitions conflict with LXRT */ |
|
+#define SPURIOUS_APIC_VECTOR 0xdf |
|
+#define ERROR_APIC_VECTOR 0xde |
|
+#define INVALIDATE_TLB_VECTOR 0xdd |
|
+#define RESCHEDULE_VECTOR 0xdc |
|
+#define CALL_FUNCTION_VECTOR 0xdb |
|
+#else |
|
#define SPURIOUS_APIC_VECTOR 0xff |
|
#define ERROR_APIC_VECTOR 0xfe |
|
#define INVALIDATE_TLB_VECTOR 0xfd |
|
#define RESCHEDULE_VECTOR 0xfc |
|
#define CALL_FUNCTION_VECTOR 0xfb |
|
+#endif |
|
|
|
/* |
|
* Local APIC timer IRQ vector is on a different priority level, |
|
* to work around the 'lost local interrupt if more than 2 IRQ |
|
* sources per level' errata. |
|
*/ |
|
+#ifdef CONFIG_RTHAL |
|
+#define LOCAL_TIMER_VECTOR 0xcf |
|
+#else |
|
#define LOCAL_TIMER_VECTOR 0xef |
|
+#endif |
|
|
|
/* |
|
* First APIC vector available to drivers: (vectors 0x30-0xee) |
|
@@ -56,7 +69,11 @@ |
|
* levels. (0x80 is the syscall vector) |
|
*/ |
|
#define FIRST_DEVICE_VECTOR 0x31 |
|
+#ifdef CONFIG_RTHAL |
|
+#define FIRST_SYSTEM_VECTOR 0xcf |
|
+#else |
|
#define FIRST_SYSTEM_VECTOR 0xef |
|
+#endif |
|
|
|
extern int irq_vector[NR_IRQS]; |
|
#define IO_APIC_VECTOR(irq) irq_vector[irq] |
|
diff -Naur linux-2.4.20/include/asm-i386/irq.h linux-2.4.20-rtai/include/asm-i386/irq.h |
|
--- linux-2.4.20/include/asm-i386/irq.h Sat Aug 3 02:39:45 2002 |
|
+++ linux-2.4.20-rtai/include/asm-i386/irq.h Mon Dec 2 16:11:55 2002 |
|
@@ -26,7 +26,7 @@ |
|
#ifdef CONFIG_X86_IO_APIC |
|
#define NR_IRQS 224 |
|
#else |
|
-#define NR_IRQS 16 |
|
+#define NR_IRQS 32 /* 2.4.19 vanilla has 16, this is rtai back compatibility */ |
|
#endif |
|
|
|
static __inline__ int irq_cannonicalize(int irq) |
|
diff -Naur linux-2.4.20/include/asm-i386/pgalloc.h linux-2.4.20-rtai/include/asm-i386/pgalloc.h |
|
--- linux-2.4.20/include/asm-i386/pgalloc.h Sat Aug 3 02:39:45 2002 |
|
+++ linux-2.4.20-rtai/include/asm-i386/pgalloc.h Mon Dec 2 16:16:00 2002 |
|
@@ -158,6 +158,33 @@ |
|
|
|
extern int do_check_pgt_cache(int, int); |
|
|
|
+extern inline void set_pgdir(unsigned long address, pgd_t entry) |
|
+{ |
|
+ struct task_struct * p; |
|
+ pgd_t *pgd; |
|
+#ifdef CONFIG_SMP |
|
+ int i; |
|
+#endif |
|
+ |
|
+ read_lock(&tasklist_lock); |
|
+ for_each_task(p) { |
|
+ if (!p->mm) |
|
+ continue; |
|
+ *pgd_offset(p->mm,address) = entry; |
|
+ } |
|
+ read_unlock(&tasklist_lock); |
|
+#ifndef CONFIG_SMP |
|
+ for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) |
|
+ pgd[address >> PGDIR_SHIFT] = entry; |
|
+#else |
|
+ /* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can |
|
+ modify pgd caches of other CPUs as well. -jj */ |
|
+ for (i = 0; i < NR_CPUS; i++) |
|
+ for (pgd = (pgd_t *)cpu_data[i].pgd_quick; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) |
|
+ pgd[address >> PGDIR_SHIFT] = entry; |
|
+#endif |
|
+} |
|
+ |
|
/* |
|
* TLB flushing: |
|
* |
|
diff -Naur linux-2.4.20/include/asm-i386/system.h linux-2.4.20-rtai/include/asm-i386/system.h |
|
--- linux-2.4.20/include/asm-i386/system.h Fri Nov 29 19:02:50 2002 |
|
+++ linux-2.4.20-rtai/include/asm-i386/system.h Mon Dec 2 16:16:00 2002 |
|
@@ -12,7 +12,12 @@ |
|
struct task_struct; /* one of the stranger aspects of C forward declarations.. */ |
|
extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)); |
|
|
|
-#define prepare_to_switch() do { } while(0) |
|
+#define prepare_to_switch() do { \ |
|
+ if (rthal.lxrt_global_cli) { \ |
|
+ rthal.lxrt_global_cli(); \ |
|
+ } \ |
|
+} while(0) |
|
+ |
|
#define switch_to(prev,next,last) do { \ |
|
asm volatile("pushl %%esi\n\t" \ |
|
"pushl %%edi\n\t" \ |
|
@@ -23,6 +28,7 @@ |
|
"pushl %4\n\t" /* restore EIP */ \ |
|
"jmp __switch_to\n" \ |
|
"1:\t" \ |
|
+ "sti\n\t" \ |
|
"popl %%ebp\n\t" \ |
|
"popl %%edi\n\t" \ |
|
"popl %%esi\n\t" \ |
|
@@ -315,29 +321,59 @@ |
|
|
|
#define set_wmb(var, value) do { var = value; wmb(); } while (0) |
|
|
|
+struct rt_hal { |
|
+ void *ret_from_intr; |
|
+ void *__switch_to; |
|
+ struct desc_struct *idt_table; |
|
+ void (*disint)(void); |
|
+ void (*enint)(void); |
|
+ unsigned int (*getflags)(void); |
|
+ void (*setflags)(unsigned int flags); |
|
+ unsigned int (*getflags_and_cli)(void); |
|
+ void *irq_desc; |
|
+ int *irq_vector; |
|
+ unsigned long *irq_affinity; |
|
+ void (*smp_invalidate_interrupt)(void); |
|
+ void (*ack_8259_irq)(unsigned int); |
|
+ int *idle_weight; |
|
+ void (*lxrt_global_cli)(void); |
|
+ void (*switch_mem)(struct task_struct *, struct task_struct *, int); |
|
+ struct task_struct **init_tasks; |
|
+ unsigned int *apicmap; |
|
+}; |
|
+ |
|
+extern struct rt_hal rthal; |
|
+ |
|
/* interrupt control.. */ |
|
-#define __save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) |
|
-#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc") |
|
-#define __cli() __asm__ __volatile__("cli": : :"memory") |
|
-#define __sti() __asm__ __volatile__("sti": : :"memory") |
|
-/* used in the idle loop; sti takes one instruction cycle to complete */ |
|
-#define safe_halt() __asm__ __volatile__("sti; hlt": : :"memory") |
|
+#define hard_save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) |
|
+#define hard_restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc") |
|
+#define hard_cli() __asm__ __volatile__("cli": : :"memory") |
|
+#define hard_sti() __asm__ __volatile__("sti": : :"memory") |
|
+#define hard_save_flags_and_cli(x) __asm__ __volatile__("pushfl; popl %0; cli":"=g" (x): /* no input */) |
|
+ |
|
+#define __cli() do { rthal.disint(); } while (0) |
|
+#define __sti() do { rthal.enint(); } while (0) |
|
+#define __save_flags(x) do { x = rthal.getflags(); } while (0) |
|
+#define __restore_flags(x) do { rthal.setflags(x); } while (0) |
|
+ |
|
+#define __save_and_cli(x) do { x = rthal.getflags_and_cli(); } while (0) |
|
+#define __save_and_sti(x) do { x = rthal.getflags(); rthal.enint(); } while (0) |
|
|
|
-#define __save_and_cli(x) do { __save_flags(x); __cli(); } while(0); |
|
-#define __save_and_sti(x) do { __save_flags(x); __sti(); } while(0); |
|
+/* used in the idle loop; sti takes one instruction cycle to complete */ |
|
+#define safe_halt() __asm__ __volatile__("call *"SYMBOL_NAME_STR(rthal + 16)"; hlt": : :"memory") |
|
|
|
/* For spinlocks etc */ |
|
#if 0 |
|
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory") |
|
#define local_irq_set(x) __asm__ __volatile__("pushfl ; popl %0 ; sti":"=g" (x): /* no input */ :"memory") |
|
#else |
|
-#define local_irq_save(x) __save_and_cli(x) |
|
-#define local_irq_set(x) __save_and_sti(x) |
|
+#define local_irq_save(x) do { x = rthal.getflags_and_cli(); } while (0) |
|
+#define local_irq_set(x) do { x = rthal.getflags(); rthal.enint(); } while (0) |
|
#endif |
|
|
|
-#define local_irq_restore(x) __restore_flags(x) |
|
-#define local_irq_disable() __cli() |
|
-#define local_irq_enable() __sti() |
|
+#define local_irq_restore(x) do { rthal.setflags(x); } while (0) |
|
+#define local_irq_disable() do { rthal.disint(); } while (0) |
|
+#define local_irq_enable() do { rthal.enint(); } while (0) |
|
|
|
#ifdef CONFIG_SMP |
|
|
|
diff -Naur linux-2.4.20/include/asm-ppc/system.h linux-2.4.20-rtai/include/asm-ppc/system.h |
|
--- linux-2.4.20/include/asm-ppc/system.h Sat Aug 3 02:39:45 2002 |
|
+++ linux-2.4.20-rtai/include/asm-ppc/system.h Mon Dec 2 16:11:55 2002 |
|
@@ -82,6 +82,7 @@ |
|
|
|
struct task_struct; |
|
#define prepare_to_switch() do { } while(0) |
|
+#define end_switch() do { } while(0) |
|
#define switch_to(prev,next,last) _switch_to((prev),(next),&(last)) |
|
extern void _switch_to(struct task_struct *, struct task_struct *, |
|
struct task_struct **); |
|
diff -Naur linux-2.4.20/include/linux/sched.h linux-2.4.20-rtai/include/linux/sched.h |
|
--- linux-2.4.20/include/linux/sched.h Fri Nov 29 19:03:06 2002 |
|
+++ linux-2.4.20-rtai/include/linux/sched.h Mon Dec 2 16:16:00 2002 |
|
@@ -415,6 +415,8 @@ |
|
|
|
/* journalling filesystem info */ |
|
void *journal_info; |
|
+ |
|
+ void *this_rt_task[2]; |
|
}; |
|
|
|
/* |
|
@@ -509,6 +511,7 @@ |
|
blocked: {{0}}, \ |
|
alloc_lock: SPIN_LOCK_UNLOCKED, \ |
|
journal_info: NULL, \ |
|
+ this_rt_task: {0,0}, \ |
|
} |
|
|
|
|
|
diff -Naur linux-2.4.20/kernel/exit.c linux-2.4.20-rtai/kernel/exit.c |
|
--- linux-2.4.20/kernel/exit.c Fri Nov 29 19:03:07 2002 |
|
+++ linux-2.4.20-rtai/kernel/exit.c Mon Dec 2 16:11:55 2002 |
|
@@ -422,6 +422,71 @@ |
|
write_unlock_irq(&tasklist_lock); |
|
} |
|
|
|
+// |
|
+// PGGC added these lines to callback rtai when a task dies. |
|
+// A list of functions allows different rt_modules to be informed. |
|
+// |
|
+static struct t_callback { |
|
+ void (*rtai_callback)(struct task_struct *tsk); |
|
+ struct t_callback *next; |
|
+ } *rtai_callback_list; |
|
+ |
|
+extern int set_rtai_callback( void (*fun)(struct task_struct *tsk)); |
|
+extern void remove_rtai_callback( void (*fun)(struct task_struct *tsk)); |
|
+ |
|
+void inform_rtai(void) |
|
+{ |
|
+ struct t_callback *pt; |
|
+ |
|
+ pt = rtai_callback_list; |
|
+ while (pt) { |
|
+ (*(pt->rtai_callback))(current); |
|
+ pt = pt->next; |
|
+ } |
|
+//printk( "Task pid %d going down\n", current->pid); |
|
+} |
|
+ |
|
+int set_rtai_callback( void (*pt)(struct task_struct *tsk)) |
|
+{ |
|
+ struct t_callback *ptn; |
|
+ |
|
+ ptn = kmalloc(sizeof(struct t_callback), GFP_KERNEL); |
|
+ if (!ptn) { |
|
+ return -ENOMEM; |
|
+ } |
|
+ ptn->rtai_callback = pt; |
|
+ ptn->next = rtai_callback_list ? rtai_callback_list : 0; |
|
+ rtai_callback_list = ptn; |
|
+ return 0; |
|
+} |
|
+ |
|
+void remove_rtai_callback(void (*pt)(struct task_struct *tsk)) |
|
+{ |
|
+ struct t_callback *pto, *ptoo, *ptd; |
|
+ |
|
+ pto = rtai_callback_list; |
|
+ ptoo = 0; |
|
+ while (pto) { |
|
+ if (pto->rtai_callback == pt) { |
|
+ if (!ptoo) { |
|
+ rtai_callback_list = pto->next; |
|
+ } else { |
|
+ ptoo->next = pto->next; |
|
+ } |
|
+ ptd = pto; |
|
+ pto = pto->next; |
|
+ kfree(ptd); |
|
+ } else { |
|
+ ptoo = pto; |
|
+ pto = pto->next; |
|
+ } |
|
+ } |
|
+//printk("rtai_callback_list %X\n", rtai_callback_list); |
|
+} |
|
+// |
|
+// |
|
+// |
|
+ |
|
NORET_TYPE void do_exit(long code) |
|
{ |
|
struct task_struct *tsk = current; |
|
@@ -439,6 +504,18 @@ |
|
#ifdef CONFIG_BSD_PROCESS_ACCT |
|
acct_process(code); |
|
#endif |
|
+ |
|
+/* |
|
+ * PGGC added these lines to callback rtai when a task dies. |
|
+ * This assumes that a LXRT task should/will always set its |
|
+ * scheduling police to SCHED_FIFO or SCHED_RR. |
|
+ * We may want to enforce this in rt_task_init(...). |
|
+ * (For the moment it is not so, thus let's inform LXRT anyhow (Paolo)) |
|
+ */ |
|
+ if(tsk->this_rt_task[0]) { |
|
+ inform_rtai(); |
|
+ } |
|
+ |
|
__exit_mm(tsk); |
|
|
|
lock_kernel(); |
|
diff -Naur linux-2.4.20/kernel/fork.c linux-2.4.20-rtai/kernel/fork.c |
|
--- linux-2.4.20/kernel/fork.c Fri Nov 29 19:03:07 2002 |
|
+++ linux-2.4.20-rtai/kernel/fork.c Mon Dec 2 16:11:55 2002 |
|
@@ -233,7 +233,9 @@ |
|
atomic_set(&mm->mm_count, 1); |
|
init_rwsem(&mm->mmap_sem); |
|
mm->page_table_lock = SPIN_LOCK_UNLOCKED; |
|
+ lock_kernel(); |
|
mm->pgd = pgd_alloc(mm); |
|
+ unlock_kernel(); |
|
mm->def_flags = 0; |
|
if (mm->pgd) |
|
return mm; |
|
@@ -265,7 +267,9 @@ |
|
inline void __mmdrop(struct mm_struct *mm) |
|
{ |
|
BUG_ON(mm == &init_mm); |
|
+ lock_kernel(); |
|
pgd_free(mm->pgd); |
|
+ unlock_kernel(); |
|
check_pgt_cache(); |
|
destroy_context(mm); |
|
free_mm(mm); |
|
diff -Naur linux-2.4.20/kernel/ksyms.c linux-2.4.20-rtai/kernel/ksyms.c |
|
--- linux-2.4.20/kernel/ksyms.c Fri Nov 29 19:03:07 2002 |
|
+++ linux-2.4.20-rtai/kernel/ksyms.c Mon Dec 2 16:11:55 2002 |
|
@@ -600,3 +600,44 @@ |
|
/* To match ksyms with System.map */ |
|
extern const char _end[]; |
|
EXPORT_SYMBOL(_end); |
|
+ |
|
+/* |
|
+ * used to inform rtai a task is about to die. |
|
+ */ |
|
+extern int set_rtai_callback( void (*fun)(struct task_struct *tsk)); |
|
+extern void remove_rtai_callback(void (*fun)(struct task_struct *tsk)); |
|
+extern NORET_TYPE void do_exit(long code); |
|
+EXPORT_SYMBOL(set_rtai_callback); |
|
+EXPORT_SYMBOL(remove_rtai_callback); |
|
+EXPORT_SYMBOL(do_exit); |
|
+ |
|
+/* |
|
+ * used to inform RTAI LXRT a task should deal with a Linux signal, and for rt_lxrt_fork() |
|
+ */ |
|
+extern int (*rtai_signal_handler)(struct task_struct *lnxt, int sig); |
|
+EXPORT_SYMBOL(rtai_signal_handler); |
|
+extern int do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size); |
|
+EXPORT_SYMBOL(do_fork); |
|
+ |
|
+/* |
|
+ * used to provide async io support (aio) to RTAI LXRT. |
|
+ */ |
|
+extern ssize_t sys_read(unsigned int fd, char * buf, size_t count); |
|
+extern ssize_t sys_write(unsigned int fd, const char * buf, size_t count); |
|
+extern ssize_t sys_pread(unsigned int fd, char * buf, |
|
+ size_t count, loff_t pos); |
|
+extern ssize_t sys_pwrite(unsigned int fd, const char * buf, |
|
+ size_t count, loff_t pos); |
|
+extern long sys_fsync(unsigned int fd); |
|
+extern long sys_fdatasync(unsigned int fd); |
|
+extern long sys_open(const char * filename, int flags, int mode); |
|
+extern long sys_close(unsigned int fd); |
|
+ |
|
+EXPORT_SYMBOL(sys_read); |
|
+EXPORT_SYMBOL(sys_write); |
|
+EXPORT_SYMBOL(sys_open); |
|
+//EXPORT_SYMBOL(sys_close); |
|
+EXPORT_SYMBOL(sys_pread); |
|
+EXPORT_SYMBOL(sys_pwrite); |
|
+EXPORT_SYMBOL(sys_fsync); |
|
+EXPORT_SYMBOL(sys_fdatasync); |
|
diff -Naur linux-2.4.20/kernel/sched.c linux-2.4.20-rtai/kernel/sched.c |
|
--- linux-2.4.20/kernel/sched.c Fri Nov 29 19:03:07 2002 |
|
+++ linux-2.4.20-rtai/kernel/sched.c Mon Dec 2 16:11:55 2002 |
|
@@ -544,6 +544,43 @@ |
|
* tasks can run. It can not be killed, and it cannot sleep. The 'state' |
|
* information in task[0] is never used. |
|
*/ |
|
+ |
|
+int idle_weight = -1000; |
|
+#define MAX_MM 1024 // How large should it be? |
|
+static struct smm_t { int in, out; struct mm_struct *mm[MAX_MM]; } smm[NR_CPUS]; |
|
+#define incpnd(x) do { x = (x + 1) & (MAX_MM - 1); } while(0) |
|
+ |
|
+static inline void pend_mm(struct mm_struct *mm, int cpu) |
|
+{ |
|
+ if (rthal.lxrt_global_cli) { |
|
+ struct smm_t *p = smm + cpu; |
|
+ p->mm[p->in] = mm; |
|
+ incpnd(p->in); |
|
+ } else { |
|
+ mmdrop(mm); |
|
+ } |
|
+} |
|
+ |
|
+static inline void drop_mm(void) |
|
+{ |
|
+ if (rthal.lxrt_global_cli) { |
|
+ struct smm_t *p = smm + smp_processor_id(); |
|
+ while (p->out != p->in) { |
|
+ mmdrop(p->mm[p->out]); |
|
+ incpnd(p->out); |
|
+ } |
|
+ } |
|
+} |
|
+ |
|
+void switch_mem(struct task_struct *prevp, struct task_struct *nextp, int cpuid) |
|
+{ |
|
+ struct mm_struct *oldmm = prevp->active_mm; |
|
+ switch_mm(oldmm, nextp->active_mm, nextp, cpuid & 0x0FFFFFFF); |
|
+ if (!nextp->mm) { |
|
+ enter_lazy_tlb(oldmm, nextp, cpuid & 0x0FFFFFFF); |
|
+ } |
|
+} |
|
+ |
|
asmlinkage void schedule(void) |
|
{ |
|
struct schedule_data * sched_data; |
|
@@ -602,7 +639,7 @@ |
|
* Default process to select.. |
|
*/ |
|
next = idle_task(this_cpu); |
|
- c = -1000; |
|
+ c = idle_weight; |
|
list_for_each(tmp, &runqueue_head) { |
|
p = list_entry(tmp, struct task_struct, run_list); |
|
if (can_schedule(p, this_cpu)) { |
|
@@ -684,7 +721,7 @@ |
|
|
|
if (!prev->mm) { |
|
prev->active_mm = NULL; |
|
- mmdrop(oldmm); |
|
+ pend_mm(oldmm, this_cpu); |
|
} |
|
} |
|
|
|
@@ -693,6 +730,7 @@ |
|
* stack. |
|
*/ |
|
switch_to(prev, next, prev); |
|
+ drop_mm(); |
|
__schedule_tail(prev); |
|
|
|
same_process: |
|
diff -Naur linux-2.4.20/kernel/signal.c linux-2.4.20-rtai/kernel/signal.c |
|
--- linux-2.4.20/kernel/signal.c Fri Nov 29 19:03:07 2002 |
|
+++ linux-2.4.20-rtai/kernel/signal.c Mon Dec 2 16:11:55 2002 |
|
@@ -1010,9 +1010,30 @@ |
|
return ret; |
|
} |
|
|
|
+// |
|
+// Add this pointer to the RTAI signal handler. |
|
+// |
|
+int (*rtai_signal_handler)(struct task_struct *lnxt, int sig); |
|
+ |
|
asmlinkage long |
|
sys_kill(int pid, int sig) |
|
{ |
|
+// Add this section to call the RTAI signal handler. |
|
+// |
|
+ { |
|
+ struct task_struct *p; |
|
+ int ret; |
|
+ |
|
+ if (rtai_signal_handler) { |
|
+ p = find_task_by_pid(pid); |
|
+ if(p && (p->policy == SCHED_FIFO || p->policy == SCHED_RR) && p->this_rt_task[0]) { |
|
+ ret = rtai_signal_handler(p, sig); |
|
+ if(!ret) return 0; //let Linux deal with it. |
|
+ } |
|
+ } |
|
+ } |
|
+ |
|
+ { |
|
struct siginfo info; |
|
|
|
info.si_signo = sig; |
|
@@ -1022,6 +1043,7 @@ |
|
info.si_uid = current->uid; |
|
|
|
return kill_something_info(sig, &info, pid); |
|
+ } |
|
} |
|
|
|
/* |
|
diff -Naur linux-2.4.20/mm/vmalloc.c linux-2.4.20-rtai/mm/vmalloc.c |
|
--- linux-2.4.20/mm/vmalloc.c Fri Nov 29 19:03:09 2002 |
|
+++ linux-2.4.20-rtai/mm/vmalloc.c Mon Dec 2 16:11:55 2002 |
|
@@ -166,6 +166,9 @@ |
|
spin_lock(&init_mm.page_table_lock); |
|
do { |
|
pmd_t *pmd; |
|
+#ifdef CONFIG_X86 |
|
+ pgd_t olddir = *dir; |
|
+#endif |
|
|
|
pmd = pmd_alloc(&init_mm, dir, address); |
|
ret = -ENOMEM; |
|
@@ -175,6 +178,10 @@ |
|
ret = -ENOMEM; |
|
if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot, pages)) |
|
break; |
|
+#ifdef CONFIG_X86 |
|
+ if (pgd_val(olddir) != pgd_val(*dir)) |
|
+ set_pgdir(address, *dir); |
|
+#endif |
|
|
|
address = (address + PGDIR_SIZE) & PGDIR_MASK; |
|
dir++;
|
|
|