From 9a71ad94f540763e4c2acedc014bdbb4a997a111 Mon Sep 17 00:00:00 2001 From: Daniel Jahre Date: Wed, 14 Apr 2004 09:06:59 +0000 Subject: [PATCH] Daniel Jahre: fixed rtai package to work with kernel 2.4.25 fixed rtai description and add small kernel patch (yes it is called 2.4.24 but works with 2.4.25 as well) [2004040714373326035] (https://www.rocklinux.net/submaster) git-svn-id: http://www.rocklinux.org/svn/rock-linux/trunk@2730 c5f82cb5-29bc-0310-9cd0-bff59a50e3bc --- package/daja77/rtai/patch-2.4.24-rthal5g | 982 +++++++++++++++++++++++ package/daja77/rtai/rtai.desc | 9 +- 2 files changed, 986 insertions(+), 5 deletions(-) create mode 100644 package/daja77/rtai/patch-2.4.24-rthal5g diff --git a/package/daja77/rtai/patch-2.4.24-rthal5g b/package/daja77/rtai/patch-2.4.24-rthal5g new file mode 100644 index 000000000..fdd265538 --- /dev/null +++ b/package/daja77/rtai/patch-2.4.24-rthal5g @@ -0,0 +1,982 @@ +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 ++ EXPORT_SYMBOL(kd_mksound); ++#endif ++ ++#include ++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 ++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 ++ ++#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++; diff --git a/package/daja77/rtai/rtai.desc b/package/daja77/rtai/rtai.desc index 815f64726..25724faa6 100644 --- a/package/daja77/rtai/rtai.desc +++ b/package/daja77/rtai/rtai.desc @@ -23,9 +23,8 @@ [I] Realtime Linux Application Interface for Linux -[T] The diet libc is a libc that is optimized for small size. It can be -[T] used to create small statically linked binaries for Linux on alpha, -[T] arm, hppa, mips, s390, sparc, ppc and i386. +[T] rtai lets you write applications with strict timing constraints +[T] for your favourite operating system. [U] http://www.rtai.org @@ -36,7 +35,7 @@ [L] GPL [S] Stable -[V] 24.1.11 +[V] 24.1.13 [P] O -----5---9 107.800 -[D] 3760003 rtai-24.1.11.tgz http://www.aero.polimi.it/RTAI/ +[D] 2752438792 rtai-24.1.13.tgz http://www.aero.polimi.it/RTAI/