Kernel 2.4.32 patches
[email protected] Wed, 06 Sep 2006 10:02:58 -0300
| Newsgroups | gmane.linux.real-time.rtlinux.general |
|---|---|
| Organization | Trana Construções Ltda. |
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format. --------------040801010308090506060506 Content-Type: multipart/alternative; boundary="------------060706090208080903020803" --------------060706090208080903020803 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Hello to all, I made a rtl3.2-rc1 patch to kernel 2.4.32. The only problem than I have = with this version after 2 months of use is the system time. However, it=20 is an old problem related by me and many others in the list, which don't = have any solution until now (the kernel patched with the RTLinux make=20 the system time run more fast than RTC ~1s/5min). The patch is attached with this message. P.S.: The gcc version used to compile the kernel and RTL is the 2.95. --=20 Robson Sales Desenvolvimento NETEL - N=FAcleo Empresarial de Tecnologia Eletr=F4nica Trana Constru=E7=F5es Ltda. Fone: +55 (85) 3495-6433 R - 223. Fax: +55 (85) 3495-4661. e-mail: [email protected] <mailto:[email protected]> --------------060706090208080903020803 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type"> <title></title> </head> <body dir="ltr" bgcolor="#ffffff" text="#000000"> <p style="margin-bottom: 0cm; margin-top: 0pt;">Hello to all,</p> <p style="margin-bottom: 0cm; margin-top: 0pt;"><br> </p> <p style="margin-bottom: 0cm; margin-top: 0pt;">I made a rtl3.2-rc1 patch to kernel 2.4.32. The only problem than I have with this version after 2 months of use is the system time. However, it is an old problem related by me and many others in the list, which don't have any solution until now (the kernel patched with the RTLinux make the system time run more fast than RTC ~1s/5min). <br> </p> <p style="margin-bottom: 0cm; margin-top: 0pt;"><br> </p> <p style="margin-bottom: 0cm; margin-top: 0pt;">The patch is attached with this message.</p> <p style="margin-bottom: 0cm; margin-top: 0pt;"><br> </p> <p style="margin-bottom: 0cm; margin-top: 0pt;">P.S.: The gcc version used to compile the kernel and RTL is the 2.95.<br> </p> <p style="margin-bottom: 0cm; margin-top: 0pt;"><br> </p> <div class="moz-signature">-- <br> <title>Assinatura Robson</title> Robson Sales <br> Desenvolvimento <br> NETEL - Núcleo Empresarial de Tecnologia Eletrônica <br> Trana Construções Ltda. <br> Fone: +55 (85) 3495-6433 R - 223. <br> Fax: +55 (85) 3495-4661. <br> e-mail: <a href="mailto:[email protected]">[email protected]</a> <br> <br> </div> </body> </html> --------------060706090208080903020803-- --------------040801010308090506060506 Content-Type: text/plain; name="kernel_patch-2.4.32-rtl3.2-rc1" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kernel_patch-2.4.32-rtl3.2-rc1" diff -rbNu linux-2.4.32/Makefile linux-2.4.32-rtl3.2-rc1/Makefile --- linux-2.4.32/Makefile 2005-11-16 16:12:54.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/Makefile 2006-07-05 14:39:02.000000000 -0300 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 32 -EXTRAVERSION = +EXTRAVERSION =-rtl3.2-rc1 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -rbNu linux-2.4.32/arch/i386/config.in linux-2.4.32-rtl3.2-rc1/arch/i386/config.in --- linux-2.4.32/arch/i386/config.in 2004-11-17 08:54:21.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/config.in 2006-07-05 14:38:26.000000000 -0300 @@ -2,11 +2,22 @@ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # -mainmenu_name "Linux Kernel Configuration" +mainmenu_name "RTLinux/GPL Kernel Configuration" define_bool CONFIG_X86 y define_bool CONFIG_SBUS n + +mainmenu_option next_comment +comment 'Enable RTLinux HAL' +define_bool CONFIG_RTLINUX y +if [ "$CONFIG_RTLINUX" = "y" ]; then + define_bool CONFIG_RTL y +fi +bool 'TLB flush points in do_IRQ' CONFIG_IRQ_TLBFLUSH +bool 'TLB flush points in net code' CONFIG_NET_TLBFLUSH +endmenu + define_bool CONFIG_UID16 y mainmenu_option next_comment diff -rbNu linux-2.4.32/arch/i386/kernel/Makefile linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/Makefile --- linux-2.4.32/arch/i386/kernel/Makefile 2005-04-03 22:42:19.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/Makefile 2006-07-05 14:38:26.000000000 -0300 @@ -30,6 +30,7 @@ endif endif +obj-$(CONFIG_RTLINUX) += rtlinux.o obj-$(CONFIG_MCA) += mca.o obj-$(CONFIG_MTRR) += mtrr.o obj-$(CONFIG_X86_MSR) += msr.o diff -rbNu linux-2.4.32/arch/i386/kernel/apic.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/apic.c --- linux-2.4.32/arch/i386/kernel/apic.c 2004-11-17 08:54:21.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/apic.c 2006-07-05 14:38:26.000000000 -0300 @@ -785,9 +785,9 @@ spin_lock_irqsave(&i8253_lock, flags); - outb_p(0x00, 0x43); - count = inb_p(0x40); - count |= inb_p(0x40) << 8; + outb(0x00, 0x43); + count = inb(0x40); + count |= inb(0x40) << 8; spin_unlock_irqrestore(&i8253_lock, flags); diff -rbNu linux-2.4.32/arch/i386/kernel/entry.S linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/entry.S --- linux-2.4.32/arch/i386/kernel/entry.S 2003-06-13 11:51:29.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/entry.S 2006-07-05 14:38:26.000000000 -0300 @@ -184,6 +184,7 @@ ENTRY(ret_from_fork) + sti pushl %ebx call SYMBOL_NAME(schedule_tail) addl $4, %esp @@ -197,11 +198,34 @@ * but we want the default path for a system call return to * go as quickly as possible which is why some of this is * less clear than it otherwise should be. + * + * (c) Victor Yodaiken 1999 + * RTLINUX_IRET emulates the turn on interrupts effect of + * iret since, under RTLinux we may have pended interrupts + * that will not be automatically enabled on an iret. */ +#ifdef CONFIG_RTLINUX +#define RTLINUX_IRET \ + movl rtl_emulate_iret,%eax; \ + testl %eax, %eax; \ + je 1f; \ + call *%eax; \ + 1: +#else +#define RTLINUX_IRET +#endif ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL +#ifdef CONFIG_RTLINUX + movl rtl_syscall_intercept,%ebx + testl %ebx, %ebx + je 991f + call *%ebx + movl ORIG_EAX(%esp), %eax +991: +#endif GET_CURRENT(%ebx) testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS jne tracesys @@ -210,17 +234,21 @@ 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(irq_control)+8) # cli from irq_control structure cmpl $0,need_resched(%ebx) jne reschedule cmpl $0,sigpending(%ebx) jne signal_return + call *(SYMBOL_NAME(irq_control)+12) # sti from irq_control structure + restore_all: + RTLINUX_IRET RESTORE_ALL ALIGN signal_return: - sti # we can get here from an interrupt handler + call *(SYMBOL_NAME(irq_control)+12) # sti from irq_control structure + RTLINUX_IRET testl $(VM_MASK),EFLAGS(%esp) movl %esp,%eax jne v86_signal_return @@ -267,6 +295,12 @@ call SYMBOL_NAME(schedule) # test jmp ret_from_sys_call +#define RTL_PUSH_VECTOR(vector,routine) \ +1: cmpl $routine, %edi; \ + jne 1f; \ + pushl $vector; \ + jmp 7f; + ENTRY(divide_error) pushl $0 # no error code pushl $ SYMBOL_NAME(do_divide_error) @@ -294,6 +328,39 @@ movl $(__KERNEL_DS),%edx movl %edx,%ds movl %edx,%es +#ifdef CONFIG_RTLINUX + movl rtl_exception_intercept,%eax + testl %eax, %eax + je 8f + RTL_PUSH_VECTOR(0,do_divide_error) + RTL_PUSH_VECTOR(1,do_debug) + RTL_PUSH_VECTOR(3,do_int3) + RTL_PUSH_VECTOR(4,do_overflow) + RTL_PUSH_VECTOR(5,do_bounds) + RTL_PUSH_VECTOR(6,do_invalid_op) + RTL_PUSH_VECTOR(8,do_double_fault) + RTL_PUSH_VECTOR(9,do_coprocessor_segment_overrun) + RTL_PUSH_VECTOR(10,do_invalid_TSS) + RTL_PUSH_VECTOR(11,do_segment_not_present) + RTL_PUSH_VECTOR(12,do_stack_segment) + RTL_PUSH_VECTOR(13,do_general_protection) + RTL_PUSH_VECTOR(14,do_page_fault) + RTL_PUSH_VECTOR(15,do_spurious_interrupt_bug) + RTL_PUSH_VECTOR(16,do_coprocessor_error) + RTL_PUSH_VECTOR(17,do_alignment_check) + RTL_PUSH_VECTOR(18,do_machine_check) + RTL_PUSH_VECTOR(19,do_simd_coprocessor_error) +1: push $-1 +7: mov %ecx, %ebx # ebx will not be corrupted by a C routine + call *%eax + popl %ecx + mov %ebx, %ecx + testl %eax, %eax + je 8f + addl $8,%esp + RESTORE_ALL +8: +#endif GET_CURRENT(%ebx) call *%edi addl $8,%esp @@ -312,6 +379,21 @@ ENTRY(device_not_available) pushl $-1 # mark this as an int SAVE_ALL +#ifdef CONFIG_RTLINUX + movl rtl_exception_intercept,%eax + testl %eax, %eax + je 8f + movl %esp,%edx + pushl $0 # no error code + pushl %edx + pushl $7 # vector + call *%eax + addl $12,%esp + testl %eax, %eax + je 8f + RESTORE_ALL +8: +#endif GET_CURRENT(%ebx) movl %cr0,%eax testl $0x4,%eax # EM (math emulation bit) diff -rbNu linux-2.4.32/arch/i386/kernel/i386_ksyms.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/i386_ksyms.c --- linux-2.4.32/arch/i386/kernel/i386_ksyms.c 2004-04-14 10:05:25.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/i386_ksyms.c 2006-07-05 14:38:26.000000000 -0300 @@ -182,6 +182,51 @@ extern int is_sony_vaio_laptop; EXPORT_SYMBOL(is_sony_vaio_laptop); +#ifdef CONFIG_RTLINUX +#include <asm/mpspec.h> +#ifdef CONFIG_X86_IO_APIC +EXPORT_SYMBOL(smp_found_config); +#endif +#include <linux/vt_kern.h> +EXPORT_SYMBOL(kd_mksound); +extern void *__start_rtlinux_funcs,*__stop_rtlinux_funcs; +EXPORT_SYMBOL(__start_rtlinux_funcs); +EXPORT_SYMBOL(__stop_rtlinux_funcs); +EXPORT_SYMBOL(irq_control); +extern unsigned long (*do_gettimeoffset)(void); +extern int use_tsc; +EXPORT_SYMBOL(do_gettimeoffset); +EXPORT_SYMBOL(use_tsc); +EXPORT_SYMBOL(tick); +extern unsigned long wall_jiffies; +extern rwlock_t xtime_lock; +EXPORT_SYMBOL(wall_jiffies); +EXPORT_SYMBOL(xtime_lock); +extern unsigned char *rtl_cached21; +EXPORT_SYMBOL(rtl_cached21); +extern void (*rtl_do_exit_handler)(long code); +extern void (*rtl_syscall_intercept)(struct pt_regs regs); +EXPORT_SYMBOL(init_tss); +EXPORT_SYMBOL(rtl_syscall_intercept); +EXPORT_SYMBOL(rtl_do_exit_handler); +#ifdef CONFIG_SMP +EXPORT_SYMBOL(flush_tlb_all); +extern int rtl_reserved_cpumask; +EXPORT_SYMBOL(rtl_reserved_cpumask); +extern unsigned long irq_affinity[NR_IRQS]; +EXPORT_SYMBOL(irq_affinity); +extern volatile int physical_apicid_2_cpu[]; +EXPORT_SYMBOL(physical_apicid_2_cpu); +extern unsigned long flush_cpumask; +EXPORT_SYMBOL(flush_cpumask); +EXPORT_SYMBOL(cpu_tlbstate); +#endif /* CONFIG_SMP */ +extern struct console *console_drivers; +EXPORT_SYMBOL(console_drivers); +EXPORT_SYMBOL(set_ldt_desc); +EXPORT_SYMBOL(default_ldt); +#endif /* CONFIG_RTLINUX */ + #ifdef CONFIG_MULTIQUAD EXPORT_SYMBOL(xquad_portio); #endif diff -rbNu linux-2.4.32/arch/i386/kernel/i8259.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/i8259.c --- linux-2.4.32/arch/i386/kernel/i8259.c 2004-08-07 20:26:04.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/i8259.c 2006-07-05 14:38:26.000000000 -0300 @@ -132,6 +132,14 @@ spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; +#ifdef CONFIG_RTLINUX +#undef spin_lock_irqsave +#define spin_lock_irqsave(lock, flags) do { rtl_hard_local_irq_save_kernel(flags); spin_lock(lock); } while (0) + +#undef spin_unlock_irqrestore +#define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); rtl_hard_local_irq_restore_kernel(flags); } while (0) +#endif + static void end_8259A_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -172,6 +180,8 @@ #define cached_21 (__byte(0,cached_irq_mask)) #define cached_A1 (__byte(1,cached_irq_mask)) +unsigned char *rtl_cached21=&cached_21; + /* * Not all IRQs can be routed through the IO-APIC, eg. on certain (older) * boards the timer interrupt is not really connected to any IO-APIC pin, @@ -344,20 +354,20 @@ outb(0xff, 0xA1); /* mask all of 8259A-2 */ /* - * outb_p - this has to work on a wide range of PC hardware. + * outb - this has to work on a wide range of PC hardware. */ - outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ - outb_p(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ - outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ + outb(0x11, 0x20); /* ICW1: select 8259A-1 init */ + outb(0x20 + 0, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ + outb(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ if (auto_eoi) - outb_p(0x03, 0x21); /* master does Auto EOI */ + outb(0x03, 0x21); /* master does Auto EOI */ else - outb_p(0x01, 0x21); /* master expects normal EOI */ + outb(0x01, 0x21); /* master expects normal EOI */ - outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ - outb_p(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ - outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ - outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode + outb(0x11, 0xA0); /* ICW1: select 8259A-2 init */ + outb(0x20 + 8, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ + outb(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ + outb(0x01, 0xA1); /* (slave's support for AEOI in flat mode is to be investigated) */ if (auto_eoi) @@ -494,8 +504,8 @@ * Set the clock to HZ Hz, we already have a valid * vector now: */ - outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ - outb_p(LATCH & 0xff , 0x40); /* LSB */ + outb(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ + outb(LATCH & 0xff , 0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ #ifndef CONFIG_VISWS diff -rbNu linux-2.4.32/arch/i386/kernel/io_apic.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/io_apic.c --- linux-2.4.32/arch/i386/kernel/io_apic.c 2004-11-17 08:54:21.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/io_apic.c 2006-07-05 14:38:26.000000000 -0300 @@ -46,6 +46,14 @@ unsigned char int_delivery_mode = dest_LowestPrio; +#ifdef CONFIG_RTLINUX +#undef spin_lock_irqsave +#define spin_lock_irqsave(lock, flags) do { rtl_hard_local_irq_save_kernel(flags); spin_lock(lock); } while (0) + +#undef spin_unlock_irqrestore +#define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); rtl_hard_local_irq_restore_kernel(flags); } while (0) +#endif + /* * # of IRQ routing registers */ diff -rbNu linux-2.4.32/arch/i386/kernel/irq.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/irq.c --- linux-2.4.32/arch/i386/kernel/irq.c 2003-11-28 15:26:19.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/irq.c 2006-07-05 14:38:26.000000000 -0300 @@ -638,12 +638,19 @@ spin_unlock(&desc->lock); handle_IRQ_event(irq, ®s, action); spin_lock(&desc->lock); +#ifdef CONFIG_IRQ_TLBFLUSH + __asm__ __volatile__("invlpg %0": :"m" (*(char *)&action)); +#endif if (!(desc->status & IRQ_PENDING)) break; desc->status &= ~IRQ_PENDING; } desc->status &= ~IRQ_INPROGRESS; + +#ifdef CONFIG_IRQ_TLBFLUSH + __asm__ __volatile__("invlpg %0": :"m" (*(char *)current)); +#endif out: /* * The ->end() handler has to deal with interrupts which got @@ -652,8 +659,12 @@ desc->handler->end(irq); spin_unlock(&desc->lock); - if (softirq_pending(cpu)) + if (softirq_pending(cpu)){ do_softirq(); +#ifdef CONFIG_IRQ_TLBFLUSH + __asm__ __volatile__("invlpg %0": :"m" (*(char *)&do_softirq)); +#endif + } return 1; } @@ -1091,7 +1102,7 @@ static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; +unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { diff -rbNu linux-2.4.32/arch/i386/kernel/nmi.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/nmi.c --- linux-2.4.32/arch/i386/kernel/nmi.c 2003-06-13 11:51:29.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/nmi.c 2006-07-05 14:38:26.000000000 -0300 @@ -344,7 +344,12 @@ * Since current-> is always on the stack, and we always switch * the stack NMI-atomically, it's safe to use smp_processor_id(). */ +#ifdef CONFIG_RTLINUX + /* For RTLinux this is not always the case, hence hard_smp_processor_id */ + int sum, cpu = hw_smp_processor_id(); +#else int sum, cpu = smp_processor_id(); +#endif sum = apic_timer_irqs[cpu]; diff -rbNu linux-2.4.32/arch/i386/kernel/pci-irq.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/pci-irq.c --- linux-2.4.32/arch/i386/kernel/pci-irq.c 2005-11-16 16:12:54.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/pci-irq.c 2006-07-05 14:38:26.000000000 -0300 @@ -573,14 +573,14 @@ */ static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - outb_p(pirq, 0xc00); + outb(pirq, 0xc00); return inb(0xc01) & 0xf; } static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - outb_p(pirq, 0xc00); - outb_p(irq, 0xc01); + outb(pirq, 0xc00); + outb(irq, 0xc01); return 1; } diff -rbNu linux-2.4.32/arch/i386/kernel/pci-irq.c~ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/pci-irq.c~ --- linux-2.4.32/arch/i386/kernel/pci-irq.c~ 1969-12-31 21:00:00.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/pci-irq.c~ 2005-11-16 16:12:54.000000000 -0300 @@ -0,0 +1,1225 @@ +/* + * Low-Level PCI Support for PC -- Routing of Interrupts + * + * (c) 1999--2000 Martin Mares <[email protected]> + */ + +#include <linux/config.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/interrupt.h> +#include <linux/irq.h> + +#include <asm/io.h> +#include <asm/smp.h> +#include <asm/io_apic.h> + +#include "pci-i386.h" + +#define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) +#define PIRQ_VERSION 0x0100 + +int broken_hp_bios_irq9; +int acer_tm360_irqrouting; + +static struct irq_routing_table *pirq_table; + +/* + * Never use: 0, 1, 2 (timer, keyboard, and cascade) + * Avoid using: 13, 14 and 15 (FP error and IDE). + * Penalize: 3, 4, 6, 7, 12 (known ISA uses: serial, floppy, parallel and mouse) + */ +unsigned int pcibios_irq_mask = 0xfff8; + +static int pirq_penalty[16] = { + 1000000, 1000000, 1000000, 1000, 1000, 0, 1000, 1000, + 0, 0, 0, 0, 1000, 100000, 100000, 100000 +}; + +struct irq_router { + char *name; + u16 vendor, device; + int (*get)(struct pci_dev *router, struct pci_dev *dev, int pirq); + int (*set)(struct pci_dev *router, struct pci_dev *dev, int pirq, int new); +}; + +struct irq_router_handler { + u16 vendor; + int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); +}; + +/* + * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. + */ + +static struct irq_routing_table * __init pirq_find_routing_table(void) +{ + u8 *addr; + struct irq_routing_table *rt; + int i; + u8 sum; + + for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { + rt = (struct irq_routing_table *) addr; + if (rt->signature != PIRQ_SIGNATURE || + rt->version != PIRQ_VERSION || + rt->size % 16 || + rt->size < sizeof(struct irq_routing_table)) + continue; + sum = 0; + for(i=0; i<rt->size; i++) + sum += addr[i]; + if (!sum) { + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + return rt; + } + } + return NULL; +} + +/* + * If we have a IRQ routing table, use it to search for peer host + * bridges. It's a gross hack, but since there are no other known + * ways how to get a list of buses, we have to go this way. + */ + +static void __init pirq_peer_trick(void) +{ + struct irq_routing_table *rt = pirq_table; + u8 busmap[256]; + int i; + struct irq_info *e; + + memset(busmap, 0, sizeof(busmap)); + for(i=0; i < (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); i++) { + e = &rt->slots[i]; +#ifdef DEBUG + { + int j; + DBG("%02x:%02x slot=%02x", e->bus, e->devfn/8, e->slot); + for(j=0; j<4; j++) + DBG(" %d:%02x/%04x", j, e->irq[j].link, e->irq[j].bitmap); + DBG("\n"); + } +#endif + busmap[e->bus] = 1; + } + for(i=1; i<256; i++) + /* + * It might be a secondary bus, but in this case its parent is already + * known (ascending bus order) and therefore pci_scan_bus returns immediately. + */ + if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL)) + printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i); + pcibios_last_bus = -1; +} + +/* + * Code for querying and setting of IRQ routes on various interrupt routers. + */ + +void eisa_set_level_irq(unsigned int irq) +{ + unsigned char mask = 1 << (irq & 7); + unsigned int port = 0x4d0 + (irq >> 3); + unsigned char val = inb(port); + + if (!(val & mask)) { + DBG(" -> edge"); + outb(val | mask, port); + } +} + +/* + * Common IRQ routing practice: nybbles in config space, + * offset by some magic constant. + */ +static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr) +{ + u8 x; + unsigned reg = offset + (nr >> 1); + + pci_read_config_byte(router, reg, &x); + return (nr & 1) ? (x >> 4) : (x & 0xf); +} + +static void write_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr, unsigned int val) +{ + u8 x; + unsigned reg = offset + (nr >> 1); + + pci_read_config_byte(router, reg, &x); + x = (nr & 1) ? ((x & 0x0f) | (val << 4)) : ((x & 0xf0) | val); + pci_write_config_byte(router, reg, x); +} + +/* + * ALI pirq entries are damn ugly, and completely undocumented. + * This has been figured out from pirq tables, and it's not a pretty + * picture. + */ +static int pirq_ali_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + static unsigned char irqmap[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 1, 11, 0, 12, 0, 14, 0, 15 }; + + return irqmap[read_config_nybble(router, 0x48, pirq-1)]; +} + +static int pirq_ali_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + static unsigned char irqmap[16] = { 0, 8, 0, 2, 4, 5, 7, 6, 0, 1, 3, 9, 11, 0, 13, 15 }; + unsigned int val = irqmap[irq]; + + if (val) { + write_config_nybble(router, 0x48, pirq-1, val); + return 1; + } + return 0; +} + +/* + * The Intel PIIX4 pirq rules are fairly simple: "pirq" is + * just a pointer to the config space. + */ +static int pirq_piix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + u8 x; + + pci_read_config_byte(router, pirq, &x); + return (x < 16) ? x : 0; +} + +static int pirq_piix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + pci_write_config_byte(router, pirq, irq); + return 1; +} + +/* + * The VIA pirq rules are nibble-based, like ALI, + * but without the ugly irq number munging. + * However, PIRQD is in the upper instead of lower nibble. + */ +static int pirq_via_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + return read_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq); +} + +static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + write_config_nybble(router, 0x55, pirq == 4 ? 5 : pirq, irq); + return 1; +} + +/* + * The VIA pirq rules are nibble-based, like ALI, + * but without the ugly irq number munging. + * However, for 82C586, nibble map is different . + */ +static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + return read_config_nybble(router, 0x55, pirqmap[pirq-1]); +} + +static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); + return 1; +} + +/* + * ITE 8330G pirq rules are nibble-based + * FIXME: pirqmap may be { 1, 0, 3, 2 }, + * 2+3 are both mapped to irq 9 on my system + */ +static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; + return read_config_nybble(router,0x43, pirqmap[pirq-1]); +} + +static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + static unsigned char pirqmap[4] = { 1, 0, 2, 3 }; + write_config_nybble(router, 0x43, pirqmap[pirq-1], irq); + return 1; +} + +/* + * OPTI: high four bits are nibble pointer.. + * I wonder what the low bits do? + */ +static int pirq_opti_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + return read_config_nybble(router, 0xb8, pirq >> 4); +} + +static int pirq_opti_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + write_config_nybble(router, 0xb8, pirq >> 4, irq); + return 1; +} + +/* + * OPTI Viper-M/N+: Bit field with 3 bits per entry. + * Due to the lack of a specification the information about this chipset + * was taken from the NetBSD source code. + */ +static int pirq_viper_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + static const int viper_irq_decode[] = { 0, 5, 9, 10, 11, 12, 14, 15 }; + u32 irq; + + pci_read_config_dword(router, 0x40, &irq); + irq >>= (pirq-1)*3; + irq &= 7; + + return viper_irq_decode[irq]; +} + +static int pirq_viper_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + static const int viper_irq_map[] = { -1, -1, -1, -1, -1, 1, -1, -1, -1, 2, 3, 4, 5, -1, 6, 7 }; + int newval = viper_irq_map[irq]; + u32 val; + u32 mask = 7 << (3*(pirq-1)); +#if 0 + mask |= 0x10000UL << (pirq-1); /* edge triggered */ +#endif + + if ( newval == -1 ) + return 0; + + pci_read_config_dword(router, 0x40, &val); + val &= ~mask; + val |= newval << (3*(pirq-1)); + pci_write_config_dword(router, 0x40, val); + + return 1; +} + +/* + * Cyrix: nibble offset 0x5C + */ +static int pirq_cyrix_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + return read_config_nybble(router, 0x5C, (pirq-1)^1); +} + +static int pirq_cyrix_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + write_config_nybble(router, 0x5C, (pirq-1)^1, irq); + return 1; +} + +/* + * PIRQ routing for SiS 85C503 router used in several SiS chipsets. + * We have to deal with the following issues here: + * - vendors have different ideas about the meaning of link values + * - some onboard devices (integrated in the chipset) have special + * links and are thus routed differently (i.e. not via PCI INTA-INTD) + * - different revision of the router have a different layout for + * the routing registers, particularly for the onchip devices + * + * For all routing registers the common thing is we have one byte + * per routeable link which is defined as: + * bit 7 IRQ mapping enabled (0) or disabled (1) + * bits [6:4] reserved (sometimes used for onchip devices) + * bits [3:0] IRQ to map to + * allowed: 3-7, 9-12, 14-15 + * reserved: 0, 1, 2, 8, 13 + * + * The config-space registers located at 0x41/0x42/0x43/0x44 are + * always used to route the normal PCI INT A/B/C/D respectively. + * Apparently there are systems implementing PCI routing table using + * link values 0x01-0x04 and others using 0x41-0x44 for PCI INTA..D. + * We try our best to handle both link mappings. + * + * Currently (2003-05-21) it appears most SiS chipsets follow the + * definition of routing registers from the SiS-5595 southbridge. + * According to the SiS 5595 datasheets the revision id's of the + * router (ISA-bridge) should be 0x01 or 0xb0. + * + * Furthermore we've also seen lspci dumps with revision 0x00 and 0xb1. + * Looks like these are used in a number of SiS 5xx/6xx/7xx chipsets. + * They seem to work with the current routing code. However there is + * some concern because of the two USB-OHCI HCs (original SiS 5595 + * had only one). YMMV. + * + * Onchip routing for router rev-id 0x01/0xb0 and probably 0x00/0xb1: + * + * 0x61: IDEIRQ: + * bits [6:5] must be written 01 + * bit 4 channel-select primary (0), secondary (1) + * + * 0x62: USBIRQ: + * bit 6 OHCI function disabled (0), enabled (1) + * + * 0x6a: ACPI/SCI IRQ: bits 4-6 reserved + * + * 0x7e: Data Acq. Module IRQ - bits 4-6 reserved + * + * We support USBIRQ (in addition to INTA-INTD) and keep the + * IDE, ACPI and DAQ routing untouched as set by the BIOS. + * + * Currently the only reported exception is the new SiS 65x chipset + * which includes the SiS 69x southbridge. Here we have the 85C503 + * router revision 0x04 and there are changes in the register layout + * mostly related to the different USB HCs with USB 2.0 support. + * + * Onchip routing for router rev-id 0x04 (try-and-error observation) + * + * 0x60/0x61/0x62/0x63: 1xEHCI and 3xOHCI (companion) USB-HCs + * bit 6-4 are probably unused, not like 5595 + */ + +#define PIRQ_SIS_IRQ_MASK 0x0f +#define PIRQ_SIS_IRQ_DISABLE 0x80 +#define PIRQ_SIS_USB_ENABLE 0x40 +#define PIRQ_SIS_DETECT_REGISTER 0x40 + +/* return value: + * -1 on error + * 0 for PCI INTA-INTD + * 0 or enable bit mask to check or set for onchip functions + */ +static inline int pirq_sis5595_onchip(int pirq, int *reg) +{ + int ret = -1; + + *reg = pirq; + switch(pirq) { + case 0x01: + case 0x02: + case 0x03: + case 0x04: + *reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + ret = 0; + break; + + case 0x62: + ret = PIRQ_SIS_USB_ENABLE; /* documented for 5595 */ + break; + + case 0x61: + case 0x6a: + case 0x7e: + printk(KERN_INFO "SiS pirq: IDE/ACPI/DAQ mapping not implemented: (%u)\n", + (unsigned) pirq); + /* fall thru */ + default: + printk(KERN_INFO "SiS router unknown request: (%u)\n", + (unsigned) pirq); + break; + } + return ret; +} + +/* return value: + * -1 on error + * 0 for PCI INTA-INTD + * 0 or enable bit mask to check or set for onchip functions + */ +static inline int pirq_sis96x_onchip(int pirq, int *reg) +{ + int ret = -1; + + *reg = pirq; + switch(pirq) { + case 0x01: + case 0x02: + case 0x03: + case 0x04: + *reg += 0x40; + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x60: + case 0x61: + case 0x62: + case 0x63: + ret = 0; + break; + + default: + printk(KERN_INFO "SiS router unknown request: (%u)\n", + (unsigned) pirq); + break; + } + return ret; +} + + +static int pirq_sis5595_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + u8 x; + int reg, check; + + check = pirq_sis5595_onchip(pirq, ®); + if (check < 0) + return 0; + + pci_read_config_byte(router, reg, &x); + if (check != 0 && !(x & check)) + return 0; + + return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); +} + +static int pirq_sis96x_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + u8 x; + int reg, check; + + check = pirq_sis96x_onchip(pirq, ®); + if (check < 0) + return 0; + + pci_read_config_byte(router, reg, &x); + if (check != 0 && !(x & check)) + return 0; + + return (x & PIRQ_SIS_IRQ_DISABLE) ? 0 : (x & PIRQ_SIS_IRQ_MASK); +} + +static int pirq_sis5595_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + u8 x; + int reg, set; + + set = pirq_sis5595_onchip(pirq, ®); + if (set < 0) + return 0; + + x = (irq & PIRQ_SIS_IRQ_MASK); + if (x == 0) + x = PIRQ_SIS_IRQ_DISABLE; + else + x |= set; + + pci_write_config_byte(router, reg, x); + + return 1; +} + +static int pirq_sis96x_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + u8 x; + int reg, set; + + set = pirq_sis96x_onchip(pirq, ®); + if (set < 0) + return 0; + + x = (irq & PIRQ_SIS_IRQ_MASK); + if (x == 0) + x = PIRQ_SIS_IRQ_DISABLE; + else + x |= set; + + pci_write_config_byte(router, reg, x); + + return 1; +} + + +/* + * VLSI: nibble offset 0x74 - educated guess due to routing table and + * config space of VLSI 82C534 PCI-bridge/router (1004:0102) + * Tested on HP OmniBook 800 covering PIRQ 1, 2, 4, 8 for onboard + * devices, PIRQ 3 for non-pci(!) soundchip and (untested) PIRQ 6 + * for the busbridge to the docking station. + */ + +static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + if (pirq > 8) { + printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); + return 0; + } + return read_config_nybble(router, 0x74, pirq-1); +} + +static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + if (pirq > 8) { + printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq); + return 0; + } + write_config_nybble(router, 0x74, pirq-1, irq); + return 1; +} + +/* + * ServerWorks: PCI interrupts mapped to system IRQ lines through Index + * and Redirect I/O registers (0x0c00 and 0x0c01). The Index register + * format is (PCIIRQ## | 0x10), e.g.: PCIIRQ10=0x1a. The Redirect + * register is a straight binary coding of desired PIC IRQ (low nibble). + * + * The 'link' value in the PIRQ table is already in the correct format + * for the Index register. There are some special index values: + * 0x00 for ACPI (SCI), 0x01 for USB, 0x02 for IDE0, 0x04 for IDE1, + * and 0x03 for SMBus. + */ +static int pirq_serverworks_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + outb_p(pirq, 0xc00); + return inb(0xc01) & 0xf; +} + +static int pirq_serverworks_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + outb_p(pirq, 0xc00); + outb_p(irq, 0xc01); + return 1; +} + +/* Support for AMD756 PCI IRQ Routing + * Jhon H. Caicedo <[email protected]> + * Jun/21/2001 0.2.0 Release, fixed to use "nybble" functions... (jhcaiced) + * Jun/19/2001 Alpha Release 0.1.0 (jhcaiced) + * The AMD756 pirq rules are nibble-based + * offset 0x56 0-3 PIRQA 4-7 PIRQB + * offset 0x57 0-3 PIRQC 4-7 PIRQD + */ +static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq) +{ + u8 irq; + irq = 0; + if (pirq <= 4) + { + irq = read_config_nybble(router, 0x56, pirq - 1); + } + printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d get irq : %2d\n", + dev->vendor, dev->device, pirq, irq); + return irq; +} + +static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + printk(KERN_INFO "AMD756: dev %04x:%04x, router pirq : %d SET irq : %2d\n", + dev->vendor, dev->device, pirq, irq); + if (pirq <= 4) + { + write_config_nybble(router, 0x56, pirq - 1, irq); + } + return 1; +} + +#ifdef CONFIG_PCI_BIOS + +static int pirq_bios_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) +{ + struct pci_dev *bridge; + int pin = pci_get_interrupt_pin(dev, &bridge); + return pcibios_set_irq_routing(bridge, pin, irq); +} + +#endif + + +static __init int intel_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + /* We must not touch 440GX even if we have tables. 440GX has + different IRQ routing weirdness */ + if(pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0, NULL) || + pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2, NULL)) + return 0; + switch(device) + { + case PCI_DEVICE_ID_INTEL_82371FB_0: + case PCI_DEVICE_ID_INTEL_82371SB_0: + case PCI_DEVICE_ID_INTEL_82371AB_0: + case PCI_DEVICE_ID_INTEL_82371MX: + case PCI_DEVICE_ID_INTEL_82443MX_0: + case PCI_DEVICE_ID_INTEL_82801AA_0: + case PCI_DEVICE_ID_INTEL_82801AB_0: + case PCI_DEVICE_ID_INTEL_82801BA_0: + case PCI_DEVICE_ID_INTEL_82801BA_10: + case PCI_DEVICE_ID_INTEL_82801CA_0: + case PCI_DEVICE_ID_INTEL_82801CA_12: + case PCI_DEVICE_ID_INTEL_82801DB_0: + case PCI_DEVICE_ID_INTEL_82801E_0: + case PCI_DEVICE_ID_INTEL_82801EB_0: + case PCI_DEVICE_ID_INTEL_ESB_0: + case PCI_DEVICE_ID_INTEL_ICH6_0: + r->name = "PIIX/ICH"; + r->get = pirq_piix_get; + r->set = pirq_piix_set; + return 1; + } + return 0; +} + +static __init int via_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + /* FIXME: We should move some of the quirk fixup stuff here */ + + /* + * work arounds for some buggy BIOSes + */ + if (device == PCI_DEVICE_ID_VIA_82C586_0) { + switch(router->device) + { + case PCI_DEVICE_ID_VIA_82C686: + /* + * Asus k7m bios wrongly reports 82C686A + * as 586-compatible + */ + device = PCI_DEVICE_ID_VIA_82C686; + break; + case PCI_DEVICE_ID_VIA_8235: + /** + * Asus a7v-x bios wrongly reports 8235 + * as 586-compatible + */ + device = PCI_DEVICE_ID_VIA_8235; + break; + } + } + + switch(device) + { + case PCI_DEVICE_ID_VIA_82C586_0: + r->name = "VIA"; + r->get = pirq_via586_get; + r->set = pirq_via586_set; + return 1; + case PCI_DEVICE_ID_VIA_82C596: + case PCI_DEVICE_ID_VIA_82C686: + case PCI_DEVICE_ID_VIA_8231: + case PCI_DEVICE_ID_VIA_8235: + /* FIXME: add new ones for 8233/5 */ + r->name = "VIA"; + r->get = pirq_via_get; + r->set = pirq_via_set; + return 1; + } + return 0; +} + +static __init int vlsi_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_VLSI_82C534: + r->name = "VLSI 82C534"; + r->get = pirq_vlsi_get; + r->set = pirq_vlsi_set; + return 1; + } + return 0; +} + + +static __init int serverworks_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_SERVERWORKS_OSB4: + case PCI_DEVICE_ID_SERVERWORKS_CSB5: + r->name = "ServerWorks"; + r->get = pirq_serverworks_get; + r->set = pirq_serverworks_set; + return 1; + } + return 0; +} + +static __init int sis_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + u8 reg; + u16 devid; + + if (device != PCI_DEVICE_ID_SI_503) + return 0; + + /* + * In case of SiS south bridge, we need to detect the two + * kinds of routing tables we have seen so far (5595 and 96x). + * Since the maintain the same device ID, we need to do poke + * the PCI configuration space to find the router type we are + * dealing with. + */ + + /* + * Factoid: writing bit6 of register 0x40 of the router config space + * will make the SB to show up 0x096x inside the device id. Note, + * we need to restore register 0x40 after the device id poke. + */ + + pci_read_config_byte(router, PIRQ_SIS_DETECT_REGISTER, ®); + pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg | (1 << 6)); + pci_read_config_word(router, PCI_DEVICE_ID, &devid); + pci_write_config_byte(router, PIRQ_SIS_DETECT_REGISTER, reg); + + if ((devid & 0xfff0) == 0x0960) { + r->name = "SIS96x"; + r->get = pirq_sis96x_get; + r->set = pirq_sis96x_set; + DBG("PCI: Detecting SiS router at %02x:%02x : SiS096x detected\n", + rt->rtr_bus, rt->rtr_devfn); + } else { + r->name = "SIS5595"; + r->get = pirq_sis5595_get; + r->set = pirq_sis5595_set; + DBG("PCI: Detecting SiS router at %02x:%02x : SiS5595 detected\n", + rt->rtr_bus, rt->rtr_devfn); + } + return 1; +} + +static __init int cyrix_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_CYRIX_5520: + r->name = "NatSemi"; + r->get = pirq_cyrix_get; + r->set = pirq_cyrix_set; + return 1; + } + return 0; +} + +static __init int opti_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_OPTI_82C700: + r->name = "OPTI"; + r->get = pirq_opti_get; + r->set = pirq_opti_set; + break; + case PCI_DEVICE_ID_OPTI_82C558: + r->name = "OPTI VIPER"; + r->get = pirq_viper_get; + r->set = pirq_viper_set; + break; + default: + return 0; + } + return 1; +} + +static __init int ite_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_ITE_IT8330G_0: + r->name = "ITE"; + r->get = pirq_ite_get; + r->set = pirq_ite_set; + return 1; + } + return 0; +} + +static __init int ali_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_AL_M1533: + r->name = "ALI"; + r->get = pirq_ali_get; + r->set = pirq_ali_set; + return 1; + /* Should add 156x some day */ + } + return 0; +} + +static __init int amd_router_probe(struct irq_router *r, struct pci_dev *router, u16 device) +{ + switch(device) + { + case PCI_DEVICE_ID_AMD_VIPER_740B: + r->name = "AMD756"; + break; + case PCI_DEVICE_ID_AMD_VIPER_7413: + r->name = "AMD766"; + break; + case PCI_DEVICE_ID_AMD_VIPER_7443: + r->name = "AMD768"; + break; + default: + return 0; + } + r->get = pirq_amd756_get; + r->set = pirq_amd756_set; + return 1; +} + +static __initdata struct irq_router_handler pirq_routers[] = { + { PCI_VENDOR_ID_INTEL, intel_router_probe }, + { PCI_VENDOR_ID_AL, ali_router_probe }, + { PCI_VENDOR_ID_ITE, ite_router_probe }, + { PCI_VENDOR_ID_VIA, via_router_probe }, + { PCI_VENDOR_ID_OPTI, opti_router_probe }, + { PCI_VENDOR_ID_SI, sis_router_probe }, + { PCI_VENDOR_ID_CYRIX, cyrix_router_probe }, + { PCI_VENDOR_ID_VLSI, vlsi_router_probe }, + { PCI_VENDOR_ID_SERVERWORKS, serverworks_router_probe }, + { PCI_VENDOR_ID_AMD, amd_router_probe }, + /* Someone with docs needs to add the ATI Radeon IGP */ + { 0, NULL } +}; +static struct irq_router pirq_router; +static struct pci_dev *pirq_router_dev; + +/* + * FIXME: should we have an option to say "generic for + * chipset" ? + */ + +static void __init pirq_find_router(struct irq_router *r) +{ + struct irq_routing_table *rt = pirq_table; + struct irq_router_handler *h; + +#ifdef CONFIG_PCI_BIOS + if (!rt->signature) { + printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n"); + r->set = pirq_bios_set; + r->name = "BIOS"; + return; + } +#endif + + /* Default unless a driver reloads it */ + r->name = "default"; + r->get = NULL; + r->set = NULL; + + DBG("PCI: Attempting to find IRQ router for %04x:%04x\n", + rt->rtr_vendor, rt->rtr_device); + + pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); + if (!pirq_router_dev) { + DBG("PCI: Interrupt router not found at %02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); + return; + } + + for( h = pirq_routers; h->vendor; h++) { + /* First look for a router match */ + if (rt->rtr_vendor == h->vendor && h->probe(r, pirq_router_dev, rt->rtr_device)) + break; + /* Fall back to a device match */ + if (pirq_router_dev->vendor == h->vendor && h->probe(r, pirq_router_dev, pirq_router_dev->device)) + break; + } + printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n", + pirq_router.name, + pirq_router_dev->vendor, + pirq_router_dev->device, + pirq_router_dev->slot_name); +} + +static struct irq_info *pirq_get_info(struct pci_dev *dev) +{ + struct irq_routing_table *rt = pirq_table; + int entries = (rt->size - sizeof(struct irq_routing_table)) / sizeof(struct irq_info); + struct irq_info *info; + + for (info = rt->slots; entries--; info++) + if (info->bus == dev->bus->number && PCI_SLOT(info->devfn) == PCI_SLOT(dev->devfn)) + return info; + return NULL; +} + +static void pcibios_test_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ +} + +static int pcibios_lookup_irq(struct pci_dev *dev, int assign) +{ + u8 pin; + struct irq_info *info; + int i, pirq, newirq; + int irq = 0; + u32 mask; + struct irq_router *r = &pirq_router; + struct pci_dev *dev2; + char *msg = NULL; + + if (!pirq_table) + return 0; + + /* Find IRQ routing entry */ + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (!pin) { + DBG(" -> no interrupt pin\n"); + return 0; + } + pin = pin - 1; + + DBG("IRQ for %s:%d", dev->slot_name, pin); + info = pirq_get_info(dev); + if (!info) { + DBG(" -> not found in routing table\n"); + return 0; + } + pirq = info->irq[pin].link; + mask = info->irq[pin].bitmap; + if (!pirq) { + DBG(" -> not routed\n"); + return 0; + } + DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs); + mask &= pcibios_irq_mask; + + /* Work around broken HP Pavilion Notebooks which assign USB to + IRQ 9 even though it is actually wired to IRQ 11 */ + + if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) { + dev->irq = 11; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); + r->set(pirq_router_dev, dev, pirq, 11); + } + + /* same for Acer Travelmate 360, but with CB and irq 11 -> 10 */ + if (acer_tm360_irqrouting && dev->irq == 11 && dev->vendor == PCI_VENDOR_ID_O2) { + pirq = 0x68; + mask = 0x400; + dev->irq = r->get(pirq_router_dev, dev, pirq); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } + + /* + * Find the best IRQ to assign: use the one + * reported by the device if possible. + */ + newirq = dev->irq; + if (!newirq && assign) { + for (i = 0; i < 16; i++) { + if (!(mask & (1 << i))) + continue; + if (pirq_penalty[i] < pirq_penalty[newirq] && + !request_irq(i, pcibios_test_irq_handler, SA_SHIRQ, "pci-test", dev)) { + free_irq(i, dev); + newirq = i; + } + } + } + DBG(" -> newirq=%d", newirq); + + /* Check if it is hardcoded */ + if ((pirq & 0xf0) == 0xf0) { + irq = pirq & 0xf; + DBG(" -> hardcoded IRQ %d\n", irq); + msg = "Hardcoded"; + } else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) { + DBG(" -> got IRQ %d\n", irq); + msg = "Found"; + } else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) { + DBG(" -> assigning IRQ %d", newirq); + if (r->set(pirq_router_dev, dev, pirq, newirq)) { + eisa_set_level_irq(newirq); + DBG(" ... OK\n"); + msg = "Assigned"; + irq = newirq; + } + } + + if (!irq) { + DBG(" ... failed\n"); + if (newirq && mask == (1 << newirq)) { + msg = "Guessed"; + irq = newirq; + } else + return 0; + } + printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name); + + /* Update IRQ for all devices with the same pirq value */ + pci_for_each_dev(dev2) { + pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin); + if (!pin) + continue; + pin--; + info = pirq_get_info(dev2); + if (!info) + continue; + if (info->irq[pin].link == pirq) { + /* We refuse to override the dev->irq information. Give a warning! */ + if (dev2->irq && dev2->irq != irq) { + printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n", + dev2->slot_name, dev2->irq, irq); + continue; + } + dev2->irq = irq; + pirq_penalty[irq]++; + if (dev != dev2) + printk(KERN_INFO "PCI: Sharing IRQ %d with %s\n", irq, dev2->slot_name); + } + } + return 1; +} + +void __init pcibios_irq_init(void) +{ + DBG("PCI: IRQ init\n"); + pirq_table = pirq_find_routing_table(); +#ifdef CONFIG_PCI_BIOS + if (!pirq_table && (pci_probe & PCI_BIOS_IRQ_SCAN)) + pirq_table = pcibios_get_irq_routing_table(); +#endif + if (pirq_table) { + pirq_peer_trick(); + pirq_find_router(&pirq_router); + if (pirq_table->exclusive_irqs) { + int i; + for (i=0; i<16; i++) + if (!(pirq_table->exclusive_irqs & (1 << i))) + pirq_penalty[i] += 100; + } + /* If we're using the I/O APIC, avoid using the PCI IRQ routing table */ + if (io_apic_assign_pci_irqs) + pirq_table = NULL; + } +} + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev; + u8 pin; + + DBG("PCI: IRQ fixup\n"); + pci_for_each_dev(dev) { + /* + * If the BIOS has set an out of range IRQ number, just ignore it. + * Also keep track of which IRQ's are already in use. + */ + if (dev->irq >= 16) { + DBG("%s: ignoring bogus IRQ %d\n", dev->slot_name, dev->irq); + dev->irq = 0; + } + /* If the IRQ is already assigned to a PCI device, ignore its ISA use penalty */ + if (pirq_penalty[dev->irq] >= 100 && pirq_penalty[dev->irq] < 100000) + pirq_penalty[dev->irq] = 0; + pirq_penalty[dev->irq]++; + } + + pci_for_each_dev(dev) { + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); +#ifdef CONFIG_X86_IO_APIC + /* + * Recalculate IRQ numbers if we use the I/O APIC. + */ + if (io_apic_assign_pci_irqs) + { + int irq; + + if (pin) { + pin--; /* interrupt pins are numbered starting from 1 */ + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + /* + * Busses behind bridges are typically not listed in the MP-table. + * In this case we have to look up the IRQ based on the parent bus, + * parent slot, and pin number. The SMP code detects such bridged + * busses itself so we should get into this branch reliably. + */ + if (irq < 0 && dev->bus->parent) { /* go back to the bridge */ + struct pci_dev * bridge = dev->bus->self; + + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); + if (irq >= 0) + printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); + } + if (irq >= 0) { + printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", + dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); + dev->irq = irq; + } + } + } +#endif + /* + * Still no IRQ? Try to lookup one... + */ + if (pin && !dev->irq) + pcibios_lookup_irq(dev, 0); + } +} + +void pcibios_penalize_isa_irq(int irq) +{ + /* + * If any ISAPnP device reports an IRQ in its list of possible + * IRQ's, we try to avoid assigning it to PCI devices. + */ + pirq_penalty[irq] += 100; +} + +void pcibios_enable_irq(struct pci_dev *dev) +{ + u8 pin; + extern int via_interrupt_line_quirk; + struct pci_dev *temp_dev; + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin && !pcibios_lookup_irq(dev, 1) && !dev->irq) { + char *msg; + + pin--; /* interrupt pins are numbered starting from 1 */ + + /* With IDE legacy devices the IRQ lookup failure is not a problem.. */ + if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE && !(dev->class & 0x5)) + return; + + if (io_apic_assign_pci_irqs) { + int irq; + + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); + /* + * Busses behind bridges are typically not listed in the MP-table. + * In this case we have to look up the IRQ based on the parent bus, + * parent slot, and pin number. The SMP code detects such bridged + * busses itself so we should get into this branch reliably. + */ + temp_dev = dev; + while (irq < 0 && dev->bus->parent) { /* go back to the bridge */ + struct pci_dev * bridge = dev->bus->self; + + pin = (pin + PCI_SLOT(dev->devfn)) % 4; + irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, + PCI_SLOT(bridge->devfn), pin); + if (irq >= 0) + printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", + bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq); + dev = bridge; + } + dev = temp_dev; + if (irq >= 0) { + printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", + dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); + dev->irq = irq; + return; + } else + msg = " Probably buggy MP table."; + } else if (pci_probe & PCI_BIOS_IRQ_SCAN) + msg = ""; + else + msg = " Please try using pci=biosirq."; + printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n", + 'A' + pin, dev->slot_name, msg); + } + /* VIA bridges use interrupt line for apic/pci steering across + the V-Link */ + else if (via_interrupt_line_quirk) + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15); + +} diff -rbNu linux-2.4.32/arch/i386/kernel/process.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/process.c --- linux-2.4.32/arch/i386/kernel/process.c 2005-11-16 16:12:54.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/process.c 2006-07-05 14:38:26.000000000 -0300 @@ -269,7 +269,7 @@ int i; for (i=0; i<0x10000; i++) - if ((inb_p(0x64) & 0x02) == 0) + if ((inb(0x64) & 0x02) == 0) break; } diff -rbNu linux-2.4.32/arch/i386/kernel/rtlinux.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/rtlinux.c --- linux-2.4.32/arch/i386/kernel/rtlinux.c 1969-12-31 21:00:00.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/rtlinux.c 2006-07-05 14:38:26.000000000 -0300 @@ -0,0 +1,80 @@ +#include <linux/config.h> +#include <linux/ptrace.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <linux/sched.h> +#include <linux/ioport.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/malloc.h> +#include <linux/random.h> +#include <linux/smp_lock.h> +#include <linux/init.h> +#include <linux/kernel_stat.h> + +#include <asm/system.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/bitops.h> +#include <asm/pgtable.h> +#include <asm/delay.h> +#include <asm/desc.h> + +#include <linux/irq.h> + +static void rtl_hard_save_flags_f(unsigned long *z){ + unsigned long y; + rtl_hard_save_flags_kernel(y); + *z=y; +} +static void rtl_hard_restore_flags_f(unsigned long x) { rtl_hard_restore_flags_kernel(x); } +static void rtl_hard_cli_f(void) { rtl_hard_cli_kernel(); } +static void rtl_hard_sti_f(void) { rtl_hard_sti_kernel(); } +static void rtl_hard_local_irq_save_f(unsigned long *x) +{ unsigned long y;rtl_hard_local_irq_save_kernel(y);*x=y; } +static void rtl_hard_local_irq_restore_f(unsigned long x){ + rtl_hard_local_irq_restore_kernel(x); +} +struct irq_control_s irq_control = { + rtl_hard_save_flags_f, + rtl_hard_restore_flags_f, + rtl_hard_cli_f, + rtl_hard_sti_f, + rtl_hard_local_irq_save_f, + rtl_hard_local_irq_restore_f + }; +void *rtl_emulate_iret = 0; +void *rtl_exception_intercept = 0; +void *rtl_syscall_intercept = 0; + +extern void *__start_rtlinux_patch,*__stop_rtlinux_patch; +extern asmlinkage void do_IRQ(struct pt_regs ); +extern void ret_from_intr(void); +RTLINUX_EXPORT(__start_rtlinux_patch); +RTLINUX_EXPORT(__stop_rtlinux_patch); +RTLINUX_EXPORT(rtl_emulate_iret); +RTLINUX_EXPORT(irq_desc); +RTLINUX_EXPORT(do_IRQ); +RTLINUX_EXPORT(ret_from_intr); +RTLINUX_EXPORT(rtl_exception_intercept); + +#ifdef CONFIG_X86_LOCAL_APIC +extern asmlinkage void smp_spurious_interrupt(void); +extern asmlinkage void smp_error_interrupt(void); +extern void smp_apic_timer_interrupt(struct pt_regs *); + +RTLINUX_EXPORT(smp_spurious_interrupt); +RTLINUX_EXPORT(smp_error_interrupt); +RTLINUX_EXPORT(smp_apic_timer_interrupt); +#endif + +#ifdef CONFIG_SMP +extern void rtl_reschedule(int cpu); +extern asmlinkage void smp_reschedule_interrupt(void); +extern asmlinkage void smp_invalidate_interrupt(void); +extern asmlinkage void smp_call_function_interrupt(void); +RTLINUX_EXPORT(smp_reschedule_interrupt); +RTLINUX_EXPORT(smp_invalidate_interrupt); +RTLINUX_EXPORT(smp_call_function_interrupt); +RTLINUX_EXPORT(rtl_reschedule); +#endif diff -rbNu linux-2.4.32/arch/i386/kernel/setup.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/setup.c --- linux-2.4.32/arch/i386/kernel/setup.c 2005-04-03 22:42:19.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/setup.c 2006-07-05 14:38:26.000000000 -0300 @@ -272,7 +272,7 @@ { int raw; - visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) + visws_board_type = (char)(inb(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG) >> PIIX_GPI_BD_SHIFT; /* * Get Board rev. @@ -280,40 +280,40 @@ * to the GPIO registers. Let's map them at 0x0fc0 which is right * after the PIIX4 PM section. */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ + outb(SIO_DEV_SEL, SIO_INDEX); + outb(SIO_GP_DEV, SIO_DATA); /* Talk to GPIO regs. */ - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ + outb(SIO_DEV_MSB, SIO_INDEX); + outb(SIO_GP_MSB, SIO_DATA); /* MSB of GPIO base address */ - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ + outb(SIO_DEV_LSB, SIO_INDEX); + outb(SIO_GP_LSB, SIO_DATA); /* LSB of GPIO base address */ - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable GPIO registers. */ + outb(SIO_DEV_ENB, SIO_INDEX); + outb(1, SIO_DATA); /* Enable GPIO registers. */ /* * Now, we have to map the power management section to write * a bit which enables access to the GPIO registers. * What lunatic came up with this shit? */ - outb_p(SIO_DEV_SEL, SIO_INDEX); - outb_p(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ + outb(SIO_DEV_SEL, SIO_INDEX); + outb(SIO_PM_DEV, SIO_DATA); /* Talk to GPIO regs. */ - outb_p(SIO_DEV_MSB, SIO_INDEX); - outb_p(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ + outb(SIO_DEV_MSB, SIO_INDEX); + outb(SIO_PM_MSB, SIO_DATA); /* MSB of PM base address */ - outb_p(SIO_DEV_LSB, SIO_INDEX); - outb_p(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ + outb(SIO_DEV_LSB, SIO_INDEX); + outb(SIO_PM_LSB, SIO_DATA); /* LSB of PM base address */ - outb_p(SIO_DEV_ENB, SIO_INDEX); - outb_p(1, SIO_DATA); /* Enable PM registers. */ + outb(SIO_DEV_ENB, SIO_INDEX); + outb(1, SIO_DATA); /* Enable PM registers. */ /* * Now, write the PM register which enables the GPIO registers. */ - outb_p(SIO_PM_FER2, SIO_PM_INDEX); - outb_p(SIO_PM_GP_EN, SIO_PM_DATA); + outb(SIO_PM_FER2, SIO_PM_INDEX); + outb(SIO_PM_GP_EN, SIO_PM_DATA); /* * Now, initialize the GPIO registers. @@ -321,7 +321,7 @@ * power on default, so let's leave them alone. * So, let's just read the board rev! */ - raw = inb_p(SIO_GP_DATA1); + raw = inb(SIO_GP_DATA1); raw &= 0x7f; /* 7 bits of valid board revision ID. */ if (visws_board_type == VISWS_320) { diff -rbNu linux-2.4.32/arch/i386/kernel/smp.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/smp.c --- linux-2.4.32/arch/i386/kernel/smp.c 2004-11-17 08:54:21.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/smp.c 2006-07-05 14:38:26.000000000 -0300 @@ -134,6 +134,10 @@ */ unsigned int cfg; +#ifdef CONFIG_RTLINUX + unsigned long flags; + rtl_hard_local_irq_save_kernel(flags); +#endif /* * Wait for idle. */ @@ -148,6 +152,9 @@ * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_restore_kernel(flags); +#endif } void fastcall send_IPI_self(int vector) @@ -160,8 +167,12 @@ unsigned long cfg; unsigned long flags; +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_save_kernel(flags); +#else __save_flags(flags); __cli(); +#endif /* @@ -185,7 +196,11 @@ */ apic_write_around(APIC_ICR, cfg); +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_restore_kernel(flags); +#else __restore_flags(flags); +#endif } static inline void send_IPI_mask_sequence(int mask, int vector) @@ -199,8 +214,12 @@ * should be modified to do 1 message per cluster ID - mbligh */ +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_save_kernel(flags); +#else __save_flags(flags); __cli(); +#endif for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { query_mask = 1 << query_cpu; @@ -231,7 +250,11 @@ apic_write_around(APIC_ICR, cfg); } } +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_restore_kernel(flags); +#else __restore_flags(flags); +#endif } static inline void send_IPI_mask(int mask, int vector) @@ -292,7 +315,7 @@ * Optimizations Manfred Spraul <[email protected]> */ -static volatile unsigned long flush_cpumask; +volatile unsigned long flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static spinlock_t tlbstate_lock = SPIN_LOCK_UNLOCKED; @@ -386,6 +409,10 @@ clear_bit(cpu, &flush_cpumask); } +#ifdef CONFIG_RTLINUX +int rtl_reserved_cpumask; +#endif + static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, unsigned long va) { @@ -416,6 +443,10 @@ flush_mm = mm; flush_va = va; atomic_set_mask(cpumask, &flush_cpumask); +#ifdef CONFIG_RTLINUX + /* make shure that reserved cpu's are excluded ! */ + atomic_clear_mask(rtl_reserved_cpumask,&flush_cpumask); +#endif /* * We have to send the IPI only to * CPUs affected. @@ -502,6 +533,13 @@ send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR); } +#ifdef CONFIG_RTLINUX +#define RTL_RESCHEDULE_VECTOR 0xEE +void rtl_reschedule(int cpu) +{ + send_IPI_mask(1 << cpu, RTL_RESCHEDULE_VECTOR); +} +#endif /* * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. diff -rbNu linux-2.4.32/arch/i386/kernel/time.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/time.c --- linux-2.4.32/arch/i386/kernel/time.c 2004-02-18 10:36:30.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/time.c 2006-07-05 14:38:26.000000000 -0300 @@ -121,7 +121,7 @@ extern spinlock_t i8259A_lock; -#ifndef CONFIG_X86_TSC +#if defined (CONFIG_RTLINUX) || ! defined (CONFIG_X86_TSC) /* This function must be called with interrupts disabled * It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs @@ -170,9 +170,9 @@ /* gets recalled with irq locally disabled */ spin_lock(&i8253_lock); /* timer count may underflow right here */ - outb_p(0x00, 0x43); /* latch the count ASAP */ + outb(0x00, 0x43); /* latch the count ASAP */ - count = inb_p(0x40); /* read the latched count */ + count = inb(0x40); /* read the latched count */ /* * We do this guaranteed double memory access instead of a _p @@ -180,12 +180,12 @@ */ jiffies_t = jiffies; - count |= inb_p(0x40) << 8; + count |= inb(0x40) << 8; /* VIA686a test code... reset the latch if count > max + 1 */ if (count > LATCH) { - outb_p(0x34, 0x43); - outb_p(LATCH & 0xff, 0x40); + outb(0x34, 0x43); + outb(LATCH & 0xff, 0x40); outb(LATCH >> 8, 0x40); count = LATCH - 1; } @@ -211,6 +211,10 @@ int i; +#ifdef CONFIG_RTLINUX + unsigned long flags; + rtl_hard_local_irq_save_kernel(flags); +#endif spin_lock(&i8259A_lock); /* * This is tricky when I/O APICs are used; @@ -218,6 +222,9 @@ */ i = inb(0x20); spin_unlock(&i8259A_lock); +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_restore_kernel(flags); +#endif /* assumption about timer being IRQ0 */ if (i & 0x01) { @@ -254,7 +261,7 @@ return count; } -static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; +unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset; /* IBM Summit (EXA) Cyclone Timer code*/ @@ -577,11 +584,18 @@ * This will also deassert NMI lines for the watchdog if run * on an 82489DX-based system. */ +#ifdef CONFIG_RTLINUX + unsigned long flags; + rtl_hard_local_irq_save_kernel(flags); +#endif spin_lock(&i8259A_lock); outb(0x0c, 0x20); /* Ack the IRQ; AEOI will end it automatically. */ inb(0x20); spin_unlock(&i8259A_lock); +#ifdef CONFIG_RTLINUX + rtl_hard_local_irq_restore_kernel(flags); +#endif } #endif @@ -629,13 +643,13 @@ high bit of the PPI port B (0x61). Note that some PS/2s, notably the 55SX, work fine if this is removed. */ - irq = inb_p( 0x61 ); /* read the current state */ - outb_p( irq|0x80, 0x61 ); /* reset the IRQ */ + irq = inb( 0x61 ); /* read the current state */ + outb( irq|0x80, 0x61 ); /* reset the IRQ */ } #endif } -static int use_tsc; +int use_tsc; /* * This is the same as the above, except we _also_ save the current @@ -675,9 +689,9 @@ rdtscl(last_tsc_low); spin_lock(&i8253_lock); - outb_p(0x00, 0x43); /* latch the count ASAP */ + outb(0x00, 0x43); /* latch the count ASAP */ - count = inb_p(0x40); /* read the latched count */ + count = inb(0x40); /* read the latched count */ count |= inb(0x40) << 8; /* Any unpaired read will cause the above to swap MSB/LSB diff -rbNu linux-2.4.32/arch/i386/kernel/traps.c linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/traps.c --- linux-2.4.32/arch/i386/kernel/traps.c 2005-11-16 16:12:54.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/kernel/traps.c 2006-07-05 14:38:26.000000000 -0300 @@ -467,11 +467,16 @@ printk("Do you have a strange power saving mode enabled?\n"); } + asmlinkage void do_nmi(struct pt_regs * regs, long error_code) { unsigned char reason = inb(0x61); +#ifdef CONFIG_RTLINUX + ++nmi_count(hw_smp_processor_id()); +#else ++nmi_count(smp_processor_id()); +#endif if (!(reason & 0xc0)) { #if CONFIG_X86_LOCAL_APIC diff -rbNu linux-2.4.32/arch/i386/mm/fault.c linux-2.4.32-rtl3.2-rc1/arch/i386/mm/fault.c --- linux-2.4.32/arch/i386/mm/fault.c 2004-08-07 20:26:04.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/mm/fault.c 2006-07-05 14:38:26.000000000 -0300 @@ -25,6 +25,9 @@ #include <asm/pgalloc.h> #include <asm/hardirq.h> +// need that for hard_sti in do_page_fault - thanks to Paolo Mantegazza . +#include <asm/rtlinux_cli.h> + extern void die(const char *,struct pt_regs *,long); /* @@ -153,8 +156,8 @@ /* It's safe to allow irq's after cr2 has been saved */ if (regs->eflags & X86_EFLAGS_IF) - local_irq_enable(); - +// local_irq_enable(); + rtl_hard_sti_kernel(); tsk = current; /* diff -rbNu linux-2.4.32/arch/i386/mm/ioremap.c linux-2.4.32-rtl3.2-rc1/arch/i386/mm/ioremap.c --- linux-2.4.32/arch/i386/mm/ioremap.c 2003-11-28 15:26:19.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/arch/i386/mm/ioremap.c 2006-07-05 14:38:26.000000000 -0300 @@ -82,6 +82,7 @@ phys_addr + address, flags)) break; error = 0; + set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; } while (address && (address < end)); diff -rbNu linux-2.4.32/config_rtl linux-2.4.32-rtl3.2-rc1/config_rtl --- linux-2.4.32/config_rtl 1969-12-31 21:00:00.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/config_rtl 2006-07-05 14:38:26.000000000 -0300 @@ -0,0 +1,1009 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_X86=y +# CONFIG_SBUS is not set + +# +# Enable RTLinux HAL +# +CONFIG_RTLINUX=y +CONFIG_RTL=y +CONFIG_IRQ_TLBFLUSH=y +CONFIG_NET_TLBFLUSH=y +CONFIG_UID16=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Processor type and features +# +# CONFIG_M386 is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M586TSC is not set +# CONFIG_M586MMX is not set +# CONFIG_M686 is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUM4 is not set +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +# CONFIG_MELAN is not set +# CONFIG_MCRUSOE is not set +# CONFIG_MWINCHIPC6 is not set +# CONFIG_MWINCHIP2 is not set +# CONFIG_MWINCHIP3D is not set +# CONFIG_MCYRIXIII is not set +# CONFIG_MVIAC3_2 is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_INVLPG=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_XADD=y +CONFIG_X86_BSWAP=y +CONFIG_X86_POPAD_OK=y +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_X86_L1_CACHE_SHIFT=5 +CONFIG_X86_USE_STRING_486=y +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_PPRO_FENCE=y +# CONFIG_X86_F00F_WORKS_OK is not set +# CONFIG_X86_MCE is not set +# CONFIG_TOSHIBA is not set +# CONFIG_I8K is not set +# CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +# CONFIG_X86_CPUID is not set +# CONFIG_EDD is not set +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIGHMEM is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_MTRR is not set +# CONFIG_SMP is not set +# CONFIG_X86_UP_APIC is not set +# CONFIG_X86_UP_IOAPIC is not set +# CONFIG_X86_TSC_DISABLE is not set + +# +# General setup +# +CONFIG_NET=y +CONFIG_PCI=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +CONFIG_PCI_GOANY=y +CONFIG_PCI_BIOS=y +CONFIG_PCI_DIRECT=y +# CONFIG_ISA is not set +CONFIG_PCI_NAMES=y +# CONFIG_EISA is not set +# CONFIG_MCA is not set +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set +# CONFIG_HOTPLUG_PCI is not set +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_SYSCTL=y +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_OOM_KILLER is not set +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# ACPI Support +# +# CONFIG_ACPI is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_CISS_MONITOR_THREAD is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_NAT=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_TOS=y +CONFIG_IP_ROUTE_VERBOSE=y +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +# CONFIG_IP_PIMSM_V2 is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# IP: Virtual Server Configuration +# +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_TAB_BITS=12 + +# +# IPVS scheduler +# +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_WRR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_NQ=m + +# +# IPVS application helper +# +CONFIG_IP_VS_FTP=m +CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_KHTTPD=m + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_ATM is not set +CONFIG_VLAN_8021Q=m + +# +# +# +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_ATALK=m + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +CONFIG_DECNET=m +# CONFIG_DECNET_SIOCGIFCONF is not set +# CONFIG_DECNET_ROUTER is not set +CONFIG_BRIDGE=m +CONFIG_X25=m +CONFIG_LAPB=m +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_CSZ=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_IDEDISK_STROKE is not set +# CONFIG_BLK_DEV_IDECS is not set +# CONFIG_BLK_DEV_DELKIN is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDESCSI=m +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_BLK_DEV_CMD640=y +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +CONFIG_BLK_DEV_ADMA100=y +CONFIG_BLK_DEV_AEC62XX=y +CONFIG_BLK_DEV_ALI15X3=y +# CONFIG_WDC_ALI15X3 is not set +CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_AMD74XX_OVERRIDE is not set +CONFIG_BLK_DEV_ATIIXP=y +CONFIG_BLK_DEV_CMD64X=y +CONFIG_BLK_DEV_TRIFLEX=y +# CONFIG_BLK_DEV_CY82C693 is not set +CONFIG_BLK_DEV_CS5530=y +CONFIG_BLK_DEV_HPT34X=y +# CONFIG_HPT34X_AUTODMA is not set +CONFIG_BLK_DEV_HPT366=y +CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_PDC202XX_OLD=y +# CONFIG_PDC202XX_BURST is not set +CONFIG_BLK_DEV_PDC202XX_NEW=y +# CONFIG_PDC202XX_FORCE is not set +CONFIG_BLK_DEV_RZ1000=y +CONFIG_BLK_DEV_SC1200=y +CONFIG_BLK_DEV_SVWKS=y +CONFIG_BLK_DEV_SIIMAGE=y +CONFIG_BLK_DEV_SIS5513=y +CONFIG_BLK_DEV_SLC90E66=y +# CONFIG_BLK_DEV_TRM290 is not set +CONFIG_BLK_DEV_VIA82CXXX=y +# CONFIG_IDE_CHIPSETS is not set +CONFIG_IDEDMA_AUTO=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_PDC202XX=y +CONFIG_BLK_DEV_ATARAID=m +CONFIG_BLK_DEV_ATARAID_PDC=m +CONFIG_BLK_DEV_ATARAID_HPT=m +CONFIG_BLK_DEV_ATARAID_MEDLEY=m +CONFIG_BLK_DEV_ATARAID_SII=m + +# +# SCSI support +# +CONFIG_SCSI=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=m +CONFIG_CHR_DEV_OSST=m +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=m + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_DEBUG_QUEUES=y +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI low-level drivers +# +CONFIG_BLK_DEV_3W_XXXX_RAID=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_PROBE_EISA_VL is not set +# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC79XX=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +# CONFIG_AIC79XX_BUILD_FIRMWARE is not set +# CONFIG_AIC79XX_ENABLE_RD_STRM is not set +# CONFIG_AIC79XX_DEBUG_ENABLE is not set +CONFIG_AIC79XX_DEBUG_MASK=0 +# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set +CONFIG_SCSI_AIC7XXX_OLD=m +# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set +CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8 +# CONFIG_AIC7XXX_OLD_PROC_STATS is not set +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_AM53C974=m +CONFIG_SCSI_MEGARAID=m +CONFIG_SCSI_MEGARAID2=m +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +CONFIG_SCSI_BUSLOGIC=m +# CONFIG_SCSI_OMIT_FLASHPOINT is not set +CONFIG_SCSI_CPQFCTS=m +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set +# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_DMA=m +CONFIG_SCSI_EATA_PIO=m +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_G_NCR5380_PORT=y +# CONFIG_SCSI_G_NCR5380_MEM is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C7xx=m +# CONFIG_SCSI_NCR53C7xx_sync is not set +# CONFIG_SCSI_NCR53C7xx_FAST is not set +# CONFIG_SCSI_NCR53C7xx_DISCONNECT is not set +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_NCR53C8XX=m +CONFIG_SCSI_SYM53C8XX=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +CONFIG_SCSI_NCR53C8XX_PQS_PDS=y +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PCI2000=m +CONFIG_SCSI_PCI2220I=m +CONFIG_SCSI_PSI240I=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_QLOGIC_ISP=m +CONFIG_SCSI_QLOGIC_FC=m +CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SEAGATE=m +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_DC390T=m +# CONFIG_SCSI_DC390T_NOGENSUPP is not set +CONFIG_SCSI_T128=m +CONFIG_SCSI_U14_34F=m +# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_DEBUG=m + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_BOOT is not set +# CONFIG_FUSION_ISENSE is not set +# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION_LAN is not set + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +CONFIG_ARCNET=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARCNET_COM20020=m +# CONFIG_ARCNET_COM20020_ISA is not set +CONFIG_ARCNET_COM20020_PCI=m +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PIO is not set +# CONFIG_E100 is not set +# CONFIG_LNE390 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_FORCEDETH is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNDANCE_MMIO is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_RHINE_MMIO is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_UINPUT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=512 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set +# CONFIG_MK712_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPMI_PANIC_EVENT is not set +# CONFIG_IPMI_DEVICE_INTERFACE is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_IPMI_WATCHDOG is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_SCx200 is not set +# CONFIG_SCx200_GPIO is not set +# CONFIG_AMD_RNG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +CONFIG_RTC=y +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_SONYPI is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set + +# +# Direct Rendering Manager (XFree86 DRI support) +# +# CONFIG_DRM is not set +# CONFIG_MWAVE is not set +# CONFIG_OBMOUSE is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +CONFIG_QUOTA=y +# CONFIG_QFMT_V2 is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +CONFIG_EXT3_FS=y +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +CONFIG_TMPFS=y +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +# CONFIG_JOLIET is not set +CONFIG_ZISOFS=y +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set +# CONFIG_XFS_FS is not set +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_RT is not set +# CONFIG_XFS_TRACE is not set +# CONFIG_XFS_DEBUG is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_ROOT_NFS is not set +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +CONFIG_ZISOFS_FS=y + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Console drivers +# +CONFIG_VGA_CONSOLE=y +CONFIG_VIDEO_SELECT=y +# CONFIG_MDA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_IOVIRT is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_FRAME_POINTER is not set +CONFIG_LOG_BUF_SHIFT=0 + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +# CONFIG_CRYPTO_WP512 is not set +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_TEST=m + +# +# Library routines +# +CONFIG_CRC32=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=m diff -rbNu linux-2.4.32/drivers/scsi/53c8xx_d.h linux-2.4.32-rtl3.2-rc1/drivers/scsi/53c8xx_d.h --- linux-2.4.32/drivers/scsi/53c8xx_d.h 1999-12-08 21:17:55.000000000 -0200 +++ linux-2.4.32-rtl3.2-rc1/drivers/scsi/53c8xx_d.h 2006-07-05 14:38:26.000000000 -0300 @@ -447,10 +447,8 @@ ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset. ABSOLUTE int_debug_break = 0x03000000 ; Break point - ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver - ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete @@ -460,7 +458,6 @@ ; each one. - ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source diff -rbNu linux-2.4.32/include/asm-i386/apic.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/apic.h --- linux-2.4.32/include/asm-i386/apic.h 2004-11-17 08:54:22.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/apic.h 2006-07-05 14:38:26.000000000 -0300 @@ -52,6 +52,9 @@ static inline void ack_APIC_irq(void) { +#ifdef CONFIG_RTLINUX + label_ack_APIC(); /* used to generate RTLinux patch point */ +#endif /* * ack_APIC_irq() actually gets compiled as a single instruction: * - a single rmw on Pentium/82489DX diff -rbNu linux-2.4.32/include/asm-i386/floppy.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/floppy.h --- linux-2.4.32/include/asm-i386/floppy.h 2003-06-13 11:51:38.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/floppy.h 2006-07-05 14:38:26.000000000 -0300 @@ -30,9 +30,11 @@ #define SW fd_routine[use_virtual_dma&1] #define CSW fd_routine[can_use_virtual_dma & 1] - -#define fd_inb(port) inb_p(port) -#define fd_outb(port,value) outb_p(port,value) +/* lets see if floppies can live with outb/inb....hofrat */ +//#define fd_inb(port) inb_p(port) +//#define fd_outb(port,value) outb_p(port,value) +#define fd_inb(port) inb(port) +#define fd_outb(port,value) outb(port,value) #define fd_request_dma() CSW._request_dma(FLOPPY_DMA,"floppy") #define fd_free_dma() CSW._free_dma(FLOPPY_DMA) diff -rbNu linux-2.4.32/include/asm-i386/hw_irq.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/hw_irq.h --- linux-2.4.32/include/asm-i386/hw_irq.h 2003-08-25 08:44:43.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/hw_irq.h 2006-07-05 14:38:26.000000000 -0300 @@ -15,6 +15,7 @@ #include <linux/config.h> #include <asm/atomic.h> #include <asm/irq.h> +#include <asm/rtlinux.h> /* * IDT vectors usable for external interrupt sources start @@ -126,41 +127,39 @@ #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) #define XBUILD_SMP_INTERRUPT(x,v)\ asmlinkage void x(void); \ -asmlinkage void call_##x(void); \ __asm__( \ "\n"__ALIGN_STR"\n" \ SYMBOL_NAME_STR(x) ":\n\t" \ - "pushl $"#v"-256\n\t" \ + "pushl $"#v"\n\t" \ SAVE_ALL \ - SYMBOL_NAME_STR(call_##x)":\n\t" \ - "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "pushl $ret_from_intr\n\t" \ + RTLINUX_LABEL(smp_##x)\ + "jmp "SYMBOL_NAME_STR(smp_##x)"\n\t" \ "jmp ret_from_intr\n"); #define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) #define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ asmlinkage void x(struct pt_regs * regs); \ -asmlinkage void call_##x(void); \ __asm__( \ "\n"__ALIGN_STR"\n" \ SYMBOL_NAME_STR(x) ":\n\t" \ - "pushl $"#v"-256\n\t" \ + "pushl $"#v"\n\t" \ SAVE_ALL \ "movl %esp,%eax\n\t" \ "pushl %eax\n\t" \ - SYMBOL_NAME_STR(call_##x)":\n\t" \ + RTLINUX_LABEL(smp_##x)\ "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ "addl $4,%esp\n\t" \ "jmp ret_from_intr\n"); #define BUILD_COMMON_IRQ() \ -asmlinkage void call_do_IRQ(void); \ __asm__( \ "\n" __ALIGN_STR"\n" \ "common_interrupt:\n\t" \ SAVE_ALL \ - SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \ - "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \ - "jmp ret_from_intr\n"); + "pushl $ret_from_intr\n\t" \ + RTLINUX_LABEL(do_IRQ)"\n\t" \ + "jmp "SYMBOL_NAME_STR(do_IRQ)); /* * subtle. orig_eax is used by the signal code to distinct between diff -rbNu linux-2.4.32/include/asm-i386/irq.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/irq.h --- linux-2.4.32/include/asm-i386/irq.h 2002-08-02 21:39:45.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/irq.h 2006-07-05 14:38:26.000000000 -0300 @@ -23,7 +23,7 @@ * Since vectors 0x00-0x1f are used/reserved for the CPU, * the usable vector space is 0x20-0xff (224 vectors) */ -#ifdef CONFIG_X86_IO_APIC +#if defined( CONFIG_X86_IO_APIC ) || defined ( CONFIG_RTLINUX ) #define NR_IRQS 224 #else #define NR_IRQS 16 @@ -37,6 +37,7 @@ extern void disable_irq(unsigned int); extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); +struct task_struct; extern void release_x86_irqs(struct task_struct *); #ifdef CONFIG_X86_LOCAL_APIC diff -rbNu linux-2.4.32/include/asm-i386/pgalloc.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/pgalloc.h --- linux-2.4.32/include/asm-i386/pgalloc.h 2003-08-25 08:44:43.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/pgalloc.h 2006-07-05 14:38:26.000000000 -0300 @@ -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 -rbNu linux-2.4.32/include/asm-i386/rtlinux.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/rtlinux.h --- linux-2.4.32/include/asm-i386/rtlinux.h 1969-12-31 21:00:00.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/rtlinux.h 2006-07-05 14:38:26.000000000 -0300 @@ -0,0 +1,14 @@ + +/* RTLinux support for patching the running kernel. + * (c) Victor Yodaiken 1999 +*/ + +#define label_ack_APIC() xlabel_code(0x12344321) +#define xlabel_code(x) asm __volatile__(".section rtlinux_patch,\"a\"\n .align 4\n"\ + ".long 1f,"#x"\n" ".previous\n 1:\n" ); +#define RTLINUX_LABEL(x)\ + ".section rtlinux_patch,\"a\"\n .align 4\n .long 1f,"#x"\n .previous\n 1:\n" + +#define RTLINUX_EXPORT(x)\ + asm (".section rtlinux_funcs,\"a\"\n .align 4\n"\ + ".long "#x"\n .previous\n" ); diff -rbNu linux-2.4.32/include/asm-i386/rtlinux_cli.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/rtlinux_cli.h --- linux-2.4.32/include/asm-i386/rtlinux_cli.h 1969-12-31 21:00:00.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/rtlinux_cli.h 2006-07-05 14:38:26.000000000 -0300 @@ -0,0 +1,43 @@ +#ifndef RTLINUX_CLI_H +#define RTLINUX_CLI_H + +/* interrupt control.. */ +#define rtl_hard_save_flags_kernel(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory") +#define rtl_hard_restore_flags_kernel(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") +#define rtl_hard_cli_kernel() __asm__ __volatile__("cli": : :"memory") +#define rtl_hard_sti_kernel() __asm__ __volatile__("sti": : :"memory") + +/* For spinlocks etc */ +#define rtl_hard_local_irq_save_kernel(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory") +#define rtl_hard_local_irq_restore_kernel(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") +#define rtl_hard_local_irq_disable_kernel() __asm__ __volatile__("cli": : :"memory") +#define rtl_hard_local_irq_enable_kernel() __asm__ __volatile__("sti": : :"memory") +struct irq_control_s { + void (*do_save_flags)(unsigned long *); + void (*do_restore_flags)(unsigned long); + void (*do_cli)(void); + void (*do_sti)(void); + void (*do_local_irq_save)(unsigned long *); + void (*do_local_irq_restore)(unsigned long); +}; +extern struct irq_control_s irq_control; +#undef __cli +#undef __sti +#undef __save_flags +#undef __restore_flags +#undef local_irq_save +#undef local_irq_restore +#undef local_irq_disable +#undef local_irq_enable +#define __save_flags(x) irq_control.do_save_flags(&x) +#define __restore_flags(x) irq_control.do_restore_flags(x) +#define __cli() irq_control.do_cli() +#define __sti() irq_control.do_sti() +#define local_irq_save(x) irq_control.do_local_irq_save((&x)) +#define local_irq_restore(x) irq_control.do_local_irq_restore(x) +#define local_irq_disable() irq_control.do_cli() +#define local_irq_enable() irq_control.do_sti() + +#undef safe_halt +#define safe_halt() do { __asm__ __volatile__("cli; nop; sti; hlt": : :"memory"); irq_control.do_sti(); } while (0) +#endif /* RTLINUX_CLI_H */ diff -rbNu linux-2.4.32/include/asm-i386/smp.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/smp.h --- linux-2.4.32/include/asm-i386/smp.h 2004-11-17 08:54:22.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/smp.h 2006-07-05 14:38:26.000000000 -0300 @@ -11,6 +11,7 @@ #endif #ifdef CONFIG_X86_LOCAL_APIC +#include <asm/rtlinux.h> #ifndef __ASSEMBLY__ #include <asm/fixmap.h> #include <asm/bitops.h> @@ -68,6 +69,9 @@ extern volatile int cpu_to_logical_apicid[NR_CPUS]; extern volatile int logical_apicid_to_cpu[MAX_APICID]; +extern volatile int physical_apicid_2_cpu[]; +#define hw_smp_processor_id() (physical_apicid_2_cpu[hard_smp_processor_id()]) + /* * General functions that each host system must provide. */ @@ -111,5 +115,7 @@ #define PROC_CHANGE_PENALTY 15 /* Schedule penalty */ +#else +#define hw_smp_processor_id() (0) #endif #endif diff -rbNu linux-2.4.32/include/asm-i386/system.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/system.h --- linux-2.4.32/include/asm-i386/system.h 2005-11-16 16:12:54.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/system.h 2006-07-05 14:38:26.000000000 -0300 @@ -5,6 +5,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <asm/segment.h> +#include <asm/rtlinux.h> #include <linux/bitops.h> /* for LOCK_PREFIX */ #ifdef __KERNEL__ @@ -336,6 +337,9 @@ #define local_irq_disable() __cli() #define local_irq_enable() __sti() +#ifdef CONFIG_RTLINUX +#include <asm/rtlinux_cli.h> +#endif #ifdef CONFIG_SMP extern void __global_cli(void); diff -rbNu linux-2.4.32/include/asm-i386/timex.h linux-2.4.32-rtl3.2-rc1/include/asm-i386/timex.h --- linux-2.4.32/include/asm-i386/timex.h 2002-11-28 20:53:15.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/include/asm-i386/timex.h 2006-07-05 14:38:26.000000000 -0300 @@ -12,7 +12,7 @@ #ifdef CONFIG_MELAN # define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ #else -# define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ +# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */ #endif #define CLOCK_TICK_FACTOR 20 /* Factor of both 1000000 and CLOCK_TICK_RATE */ diff -rbNu linux-2.4.32/kernel/exit.c linux-2.4.32-rtl3.2-rc1/kernel/exit.c --- linux-2.4.32/kernel/exit.c 2002-11-28 20:53:15.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/kernel/exit.c 2006-07-05 14:38:26.000000000 -0300 @@ -422,10 +422,14 @@ write_unlock_irq(&tasklist_lock); } +void (*rtl_do_exit_handler)(long code) = 0; NORET_TYPE void do_exit(long code) { struct task_struct *tsk = current; + if (rtl_do_exit_handler) { + rtl_do_exit_handler(code); + } if (in_interrupt()) panic("Aiee, killing interrupt handler!"); if (!tsk->pid) diff -rbNu linux-2.4.32/kernel/fork.c linux-2.4.32-rtl3.2-rc1/kernel/fork.c --- linux-2.4.32/kernel/fork.c 2005-01-19 11:10:13.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/kernel/fork.c 2006-07-05 14:38:26.000000000 -0300 @@ -43,8 +43,8 @@ { unsigned long flags; + wq_write_lock_irqsave(&q->lock, flags); //kabi wait->flags &= ~WQ_FLAG_EXCLUSIVE; - wq_write_lock_irqsave(&q->lock, flags); __add_wait_queue(q, wait); wq_write_unlock_irqrestore(&q->lock, flags); } @@ -53,8 +53,8 @@ { unsigned long flags; + wq_write_lock_irqsave(&q->lock, flags); //kabi wait->flags |= WQ_FLAG_EXCLUSIVE; - wq_write_lock_irqsave(&q->lock, flags); __add_wait_queue_tail(q, wait); wq_write_unlock_irqrestore(&q->lock, flags); } @@ -235,7 +235,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; @@ -267,7 +269,9 @@ void fastcall __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 -rbNu linux-2.4.32/mm/vmalloc.c linux-2.4.32-rtl3.2-rc1/mm/vmalloc.c --- linux-2.4.32/mm/vmalloc.c 2004-04-14 10:05:41.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/mm/vmalloc.c 2006-07-05 14:38:26.000000000 -0300 @@ -166,6 +166,7 @@ spin_lock(&init_mm.page_table_lock); do { pmd_t *pmd; + pgd_t olddir = *dir; pmd = pmd_alloc(&init_mm, dir, address); if (!pmd) @@ -173,6 +174,10 @@ if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot, pages)) goto err; // The kernel NEVER reclaims pmds, so no need to undo pmd_alloc() here +#if defined(__i386__) + if (pgd_val(olddir) != pgd_val(*dir)) + set_pgdir(address, *dir); +#endif /* __i386__ */ address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; diff -rbNu linux-2.4.32/net/core/scm.c linux-2.4.32-rtl3.2-rc1/net/core/scm.c --- linux-2.4.32/net/core/scm.c 2005-01-19 11:10:13.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/net/core/scm.c 2006-07-05 14:38:26.000000000 -0300 @@ -105,6 +105,10 @@ fput(fpl->fp[i]); kfree(fpl); } +#ifdef CONFIG_NET_TLBFLUSH + __asm__ __volatile__("invlpg %0": :"m" (*(char *)&scm)); +// __asm__ __volatile__("invlpg %0": :"m" (*(char *)&fpl)); +#endif } int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) diff -rbNu linux-2.4.32/net/socket.c linux-2.4.32-rtl3.2-rc1/net/socket.c --- linux-2.4.32/net/socket.c 2005-01-19 11:10:14.000000000 -0300 +++ linux-2.4.32-rtl3.2-rc1/net/socket.c 2006-07-05 14:38:26.000000000 -0300 @@ -507,6 +507,10 @@ err = sock->ops->sendmsg(sock, msg, size, &scm); scm_destroy(&scm); } +#ifdef CONFIG_NET_TLBFLUSH +// __asm__ __volatile__("invlpg %0": :"m" (*(char *)&(sock->ops->sendmsg))); + __asm__ __volatile__("invlpg %0": :"m" (*(char *)&msg)); +#endif return err; } @@ -520,6 +524,10 @@ if (size >= 0) scm_recv(sock, msg, &scm, flags); +#ifdef CONFIG_NET_TLBFLUSH +// __asm__ __volatile__("invlpg %0": :"m" (*(char *)&(sock->ops->recvmsg))); + __asm__ __volatile__("invlpg %0": :"m" (*(char *)&msg)); +#endif return size; } --------------040801010308090506060506 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Rtl mailing list [email protected] http://hq.fsmlabs.com/mailman/listinfo/rtl http:/www.rtlinux-gpl.org/ --------------040801010308090506060506--