Voyager subarchitecture for 2.5.47
The only real changes from the 2.5.46 patch are:
- move to completely dynamic tsc disabling (eliminate X86_TSC config option)
- fix (ok hack) for per_cpu softirq panic caused by CPUs getting timer interrupt before cpu_up is called.
James
arch/i386/Kconfig +30 -12
@@ -253,11 +253,6 @@ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 default y -config X86_TSC - bool - depends on MWINCHIP3D || MWINCHIP2 || MCRUSOE || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || M686 || M586MMX || M586TSC - default y - config X86_GOOD_APIC bool depends on MK7 || MPENTIUM4 || MPENTIUMIII || M686 || M586MMX
@@ -335,8 +330,21 @@ Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. +config VOYAGER + bool "NCR Voyager Architecture" + ---help--- + Voyager is a MCA based 32 way capable SMP architecture proprietary + to NCR Corp. Machine classes 345x/35xx/4100/51xx are voyager based. + + *** WARNING *** + + If you do not specifically know you have a Voyager based machine, + say N here otherwise the kernel you build will not be bootable. + + config X86_UP_APIC bool "Local APIC support on uniprocessors" if !SMP + depends on !VOYAGER ---help--- A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU
@@ -788,6 +796,7 @@ menu "Power management options (ACPI, APM)" + depends on !VOYAGER source "drivers/acpi/Kconfig"
@@ -971,11 +980,12 @@ config X86_LOCAL_APIC bool - depends on !VISWS && SMP || VISWS + depends on ((!VISWS && SMP) || VISWS) && !VOYAGER default y config PCI bool "PCI support" if !VISWS + depends on !VOYAGER default y if VISWS help Find out whether you have a PCI motherboard. PCI is the name of a
@@ -990,7 +1000,7 @@ config X86_IO_APIC bool - depends on !VISWS && SMP + depends on !VISWS && SMP && !VOYAGER default y choice
@@ -1034,6 +1044,7 @@ config SCx200 tristate "NatSemi SCx200 support" + depends on !VOYAGER help This provides basic support for the National Semiconductor SCx200 processor. Right now this is just a driver for the GPIO pins.
@@ -1047,6 +1058,7 @@ config ISA bool "ISA support" + depends on !VOYAGER help Find out whether you have ISA slots on your motherboard. ISA is the name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -1071,8 +1083,9 @@ Otherwise, say N. config MCA - bool "MCA support" + bool "MCA support" if !VOYAGER depends on !VISWS + default y if VOYAGER help MicroChannel Architecture is found in some IBM PS/2 machines and laptops. It is a bus system similar to PCI or ISA. See
@@ -1614,12 +1627,12 @@ config X86_EXTRA_IRQS bool - depends on X86_LOCAL_APIC + depends on X86_LOCAL_APIC || VOYAGER default y config X86_FIND_SMP_CONFIG bool - depends on X86_LOCAL_APIC + depends on X86_LOCAL_APIC || VOYAGER default y config X86_MPPARSE
@@ -1637,15 +1650,20 @@ config X86_SMP bool - depends on SMP + depends on SMP && !VOYAGER default y config X86_HT bool - depends on SMP + depends on SMP && !VOYAGER default y config X86_BIOS_REBOOT bool + depends on !VOYAGER default y +config X86_TRAMPOLINE + bool + depends on SMP + default y
arch/i386/Makefile +4 -0
@@ -49,7 +49,11 @@ ifdef CONFIG_VISWS MACHINE := mach-visws else +ifdef CONFIG_VOYAGER +MACHINE:= mach-voyager +else MACHINE := mach-generic +endif endif HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
arch/i386/boot/compressed/head.S +4 -4
@@ -31,7 +31,7 @@ startup_32: cld cli - movl $(__KERNEL_DS),%eax + movl $(__BOOT_DS),%eax movl %eax,%ds movl %eax,%es movl %eax,%fs
@@ -74,7 +74,7 @@ popl %esi # discard address popl %esi # real mode pointer xorl %ebx,%ebx - ljmp $(__KERNEL_CS), $0x100000 + ljmp $(__BOOT_CS), $0x100000 /* * We come here, if we were loaded high.
@@ -101,7 +101,7 @@ popl %eax # hcount movl $0x100000,%edi cli # make sure we don't get interrupted - ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine + ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine /* * Routine (template) for moving the decompressed kernel in place,
@@ -124,5 +124,5 @@ movsl movl %ebx,%esi # Restore setup pointer xorl %ebx,%ebx - ljmp $(__KERNEL_CS), $0x100000 + ljmp $(__BOOT_CS), $0x100000 move_routine_end:
arch/i386/boot/compressed/misc.c +1 -1
@@ -299,7 +299,7 @@struct {long * a;short b; - } stack_start = { & user_stack [STACK_SIZE ] , __KERNEL_DS }; + } stack_start = { & user_stack [STACK_SIZE ] , __BOOT_DS };static void setup_normal_output_buffer (void ) {
arch/i386/boot/setup.S +47 -9
133 lines not on this page · raw message
arch/i386/kernel/Makefile +2 -1
@@ -20,7 +20,8 @@ obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_ACPI) += acpi.o obj-$(CONFIG_ACPI_SLEEP) += acpi_wakeup.o -obj-$(CONFIG_X86_SMP) += smp.o smpboot.o trampoline.o +obj-$(CONFIG_X86_SMP) += smp.o smpboot.o +obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o
arch/i386/kernel/cpu/common.c +0 -19
@@ -42,25 +42,6 @@ }__setup ("cachesize=" , cachesize_setup); -#ifndef CONFIG_X86_TSC -static int tsc_disable__initdata =0 ; - -static int __init tsc_setup (char *str) -{ - tsc_disable =1 ; -return 1 ; -} -#else -#define tsc_disable 0 - -static int __init tsc_setup (char *str) -{ -printk ("notsc: Kernel compiled with CONFIG_X86_TSC, cannot disable TSC.\n" ); -return 1 ; -} -#endif -__setup ("notsc" , tsc_setup); -int __init get_model_name (struct cpuinfo_x86 *c) {unsigned int *v;
arch/i386/kernel/head.S +17 -5
@@ -15,6 +15,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/desc.h> +#include <asm/cache.h> #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F
@@ -46,7 +47,7 @@ * Set segments to known values */ cld - movl $(__KERNEL_DS),%eax + movl $(__BOOT_DS),%eax movl %eax,%ds movl %eax,%es movl %eax,%fs
@@ -306,7 +307,7 @@ ENTRY(stack_start) .long init_thread_union+8192 - .long __KERNEL_DS + .long __BOOT_DS /* This is the default interrupt "handler" :-) */ int_msg:
@@ -349,12 +350,12 @@ .long idt_table # boot GDT descriptor (later on used by CPU#0): - + .word 0 # 32 bit align gdt_desc.address cpu_gdt_descr: .word GDT_ENTRIES*8-1 .long cpu_gdt_table - .fill NR_CPUS-1,6,0 # space for the other GDT descriptors + .fill NR_CPUS-1,8,0 # space for the other GDT descriptors /* * This is initialized to create an identity-mapping at 0-8M (for bootup
@@ -405,10 +406,21 @@ */ .data -ALIGN /* * The Global Descriptor Table contains 28 quadwords, per-CPU. */ +#ifdef CONFIG_SMP +/* + * The boot_gdt_table must mirror the equivalent in setup.S and is + * used only by the trampoline for booting other CPUs + */ + .align L1_CACHE_BYTES +ENTRY(boot_gdt_table) + .fill GDT_ENTRY_BOOT_CS,8,0 + .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ + .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ +#endif + .align L1_CACHE_BYTES ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* 0x0b reserved */
arch/i386/kernel/irq.c +1 -1
@@ -167,7 +167,7 @@if (cpu_online (j)) p +=seq_printf (p,"%10u " ,nmi_count (j));seq_putc (p,'\n' ); -#if CONFIG_X86_LOCAL_APIC +#ifdef CONFIG_X86_LOCAL_APIC seq_printf (p,"LOC: " );for (j =0 ; j <NR_CPUS ; j++)if (cpu_online (j))
arch/i386/kernel/timers/Makefile +2 -4
@@ -2,10 +2,8 @@ # Makefile for x86 timers # -obj-y:= timer.o +obj-y:= timer.o timer_tsc.o timer_pit.o -obj-y += timer_tsc.o -obj-y += timer_pit.o -obj-$(CONFIG_X86_CYCLONE) += timer_cyclone.o +obj-$(CONFIG_X86_CYCLONE) += timer_cyclone.o include $(TOPDIR)/Rules.make
arch/i386/kernel/timers/timer.c +0 -2
@@ -8,9 +8,7 @@/* list of timers, ordered by preference, NULL terminated */ static struct timer_opts * timers[] = { &timer_tsc, -#ifndef CONFIG_X86_TSC &timer_pit, -#endifNULL , };
arch/i386/kernel/timers/timer_pit.c +2 -0
@@ -9,7 +9,9 @@#include <linux/irq.h> #include <asm/mpspec.h> #include <asm/timer.h> +#include <asm/smp.h> #include <asm/io.h> +#include <asm/arch_hooks.h> extern spinlock_t i8259A_lock;extern spinlock_t i8253_lock;
arch/i386/kernel/timers/timer_tsc.c +16 -0
@@ -11,6 +11,10 @@#include <asm/timer.h> #include <asm/io.h> +/* processor.h for distable_tsc flag */ +#include <asm/processor.h> + +int tsc_disable__initdata =0 ;extern int x86_udelay_tsc;extern spinlock_t i8253_lock;
@@ -286,6 +290,18 @@ }return -ENODEV ; } + +/* disable flag for tsc. Takes effect by clearing the TSC cpu flag +* in cpu/common.c */ +static int __init tsc_setup (char *str) +{ + tsc_disable =1 ; +return 1 ; +} + +__setup ("notsc" , tsc_setup); + +/************************************************************/
arch/i386/kernel/trampoline.S +3 -3
@@ -54,7 +54,7 @@ lmsw %ax # into protected mode jmp flush_instr flush_instr: - ljmpl $__KERNEL_CS, $0x00100000 + ljmpl $__BOOT_CS, $0x00100000 # jump to startup_32 in arch/i386/kernel/head.S idt_48:
@@ -67,8 +67,8 @@ # gdt_48: - .word 0x0800 # gdt limit = 2048, 256 GDT entries - .long cpu_gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) + .word __BOOT_DS + 7 # gdt limit + .long boot_gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) .globl trampoline_end trampoline_end:
arch/i386/mach-voyager/setup.c +3 -0
@@ -29,6 +29,9 @@void __init pre_setup_arch_hook (void ) { +/* Voyagers run their CPUs from independent clocks, so disable +* the TSC code because we can't sync them */ + tsc_disable =1 ; }void __init trap_init_hook (void )
arch/i386/mach-voyager/voyager_basic.c +19 -9
@@ -21,6 +21,7 @@#include <linux/init.h> #include <linux/delay.h> #include <linux/reboot.h> +#include <linux/sysrq.h> #include <asm/io.h> #include <asm/pgalloc.h> #include <asm/voyager.h>
@@ -41,6 +42,21 @@struct voyager_SUS *voyager_SUS =NULL ; +#ifdef CONFIG_SMP +static void +voyager_dump (int dummy1,struct pt_regs *dummy2,struct tty_struct *dummy3) +{ +/* get here via a sysrq */ +voyager_smp_dump (); +} + +static struct sysrq_key_op sysrq_voyager_dump_op = { + .handler = voyager_dump, + .help_msg ="voyager" , + .action_msg ="Dump Voyager Status\n" , +}; +#endif +void voyager_detect (struct voyager_bios_info *bios) {
@@ -62,6 +78,9 @@printk ("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n" );/* install the power off handler */ pm_power_off = voyager_power_off; +#ifdef CONFIG_SMP +register_sysrq_key ('c' , &sysrq_voyager_dump_op); +#endif }else {printk ("\n\n**WARNING**: No Voyager Subsystem Found\n" ); }
@@ -141,15 +160,6 @@ pg0[0 ] = old;local_flush_tlb ();return retval; -} - -void -voyager_dump () -{ -/* get here via a sysrq */ -#ifdef CONFIG_SMP -voyager_smp_dump (); -#endif }/* voyager specific handling code for timer interrupts. Used to hand
arch/i386/mach-voyager/voyager_smp.c +17 -40
112 lines not on this page · raw message
drivers/char/sysrq.c +1 -17
@@ -35,10 +35,6 @@#include <asm/ptrace.h> -#ifdef CONFIG_VOYAGER -#include <asm/voyager.h> -#endif -extern void reset_vc (unsigned int );extern struct list_head super_blocks;
@@ -323,14 +319,6 @@ .action_msg = "Terminate All Tasks", }; -#ifdef CONFIG_VOYAGER -static struct sysrq_key_op sysrq_voyager_dump_op = { - .handler = voyager_dump, - .help_msg ="voyager" , - .action_msg ="Dump Voyager Status\n" , -}; -#endif -static void sysrq_handle_kill (int key,struct pt_regs *pt_regs,struct tty_struct *tty) {
@@ -364,11 +352,7 @@it is handled specially on the sparc and will never arrive */ /* b */ &sysrq_reboot_op, -#ifdef CONFIG_VOYAGER -/* c */ &sysrq_voyager_dump_op, -#else -/* c */ NULL , -#endif +/* c */ NULL ,/* May be assigned at init time by SMP VOYAGER */ /* d */ NULL ,/* e */ &sysrq_term_op, /* f */ NULL,
include/asm-i386/desc.h +1 -0
@@ -13,6 +13,7 @@struct Xgt_desc_struct {unsigned short size;unsigned long address __attribute__((packed)); +unsigned short pad; } __attribute__ ((packed));extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS ];
include/asm-i386/hw_irq.h +1 -1
@@ -131,7 +131,7 @@#endif /* CONFIG_PROFILING */ -#ifdef CONFIG_SMP /*more of this file should probably be ifdefed SMP */ +#if defined(CONFIG_SMP ) && !defined(CONFIG_VOYAGER )/*more of this file should probably be ifdefed SMP */ static inline void hw_resend_irq (struct hw_interrupt_type *h,unsigned int i) {if (IO_APIC_IRQ (i))send_IPI_self (IO_APIC_VECTOR (i));
include/asm-i386/processor.h +3 -0
@@ -18,6 +18,9 @@#include <linux/config.h> #include <linux/threads.h> +/* flag for disabling the tsc */ +extern int tsc_disable; +struct desc_struct {unsigned long a,b; };
include/asm-i386/segment.h +8 -0
@@ -69,6 +69,14 @@#define GDT_SIZE (GDT_ENTRIES * 8) +/* Simple and small GDT entries for booting only */ + +#define GDT_ENTRY_BOOT_CS 2 +#define __BOOT_CS (GDT_ENTRY_BOOT_CS * 8) + +#define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) +#define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) +/* * The interrupt descriptor table has room for 256 idt's, * the global descriptor table is dependent on the number
include/asm-i386/smp.h +14 -7
@@ -6,6 +6,7 @@*/ #ifndef __ASSEMBLY__#include <linux/config.h> +#include <linux/kernel.h> #include <linux/threads.h> #endif
@@ -83,11 +84,22 @@#define cpu_possible (cpu) (cpu_callout_map & (1<<(cpu)))#define cpu_online (cpu) (cpu_online_map & (1<<(cpu))) +#define for_each_cpu (cpu, mask) \ + for(mask = cpu_online_map; \ + cpu = __ffs(mask), mask != 0; \ + mask &= ~(1<<cpu)) +extern inline unsigned int num_online_cpus (void ) {return hweight32 (cpu_online_map); } +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus (void ) +{ +return hweight32 (cpu_callout_map); +} +extern inline int any_online_cpu (unsigned int mask) {if (mask & cpu_online_map)
@@ -95,7 +107,7 @@return -1 ; } - +#ifdef CONFIG_X86_LOCAL_APIC static __inlineint hard_smp_processor_id (void ) {/* we don't want to mark this access volatile - bad code generation */
@@ -108,12 +120,7 @@return GET_APIC_LOGICAL_ID (*(unsigned long *)(APIC_BASE +APIC_LDR )); } -/* We don't mark CPUs online until __cpu_up(), so we need another measure */ -static inline int num_booting_cpus (void ) -{ -return hweight32 (cpu_callout_map); -} - +#endif #endif /* !__ASSEMBLY__ */ #define NO_PROC_ID 0xFF/* No processor magic marker */
include/asm-i386/voyager.h +0 -1
@@ -504,7 +504,6 @@extern int voyager_memory_detect (int region,__u32 *addr,__u32 *length);extern void voyager_smp_intr_init (void );extern __u8 voyager_extended_cmos_read (__u16 cmos_address); -extern void voyager_dump (void );extern void voyager_smp_dump (void );extern void voyager_timer_interrupt (struct pt_regs *regs);extern void smp_local_timer_interrupt (struct pt_regs * regs);