Voyager subarchitecture for 2.5.47

J.E.J. Bottomley (James.Bottomley@HansenPartnership.com)
Tue, 12 Nov 2002 17:37:08 -0500


This is a multipart MIME message.

--==_Exmh_-5923708860
Content-Type: text/plain; charset=us-ascii

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

--==_Exmh_-5923708860
Content-Type: text/plain ; name="voyager-2.5.47.diff"; charset=us-ascii
Content-Description: voyager-2.5.47.diff
Content-Disposition: attachment; filename="voyager-2.5.47.diff"

diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig Tue Nov 12 16:36:44 2002
+++ b/arch/i386/Kconfig Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/arch/i386/Makefile b/arch/i386/Makefile
--- a/arch/i386/Makefile Tue Nov 12 16:36:44 2002
+++ b/arch/i386/Makefile Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S
--- a/arch/i386/boot/compressed/head.S Tue Nov 12 16:36:44 2002
+++ b/arch/i386/boot/compressed/head.S Tue Nov 12 16:36:44 2002
@@ -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:
diff -Nru a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
--- a/arch/i386/boot/compressed/misc.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/boot/compressed/misc.c Tue Nov 12 16:36:44 2002
@@ -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)
{
diff -Nru a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
--- a/arch/i386/boot/setup.S Tue Nov 12 16:36:44 2002
+++ b/arch/i386/boot/setup.S Tue Nov 12 16:36:44 2002
@@ -476,6 +476,24 @@
movsb
popw %ds
no_mca:
+#ifdef CONFIG_VOYAGER
+ movb $0xff, 0x40 # flag on config found
+ movb $0xc0, %al
+ mov $0xff, %ah
+ int $0x15 # put voyager config info at es:di
+ jc no_voyager
+ movw $0x40, %si # place voyager info in apm table
+ cld
+ movw $7, %cx
+voyager_rep:
+ movb %es:(%di), %al
+ movb %al,(%si)
+ incw %di
+ incw %si
+ decw %cx
+ jnz voyager_rep
+no_voyager:
+#endif
# Check for PS/2 pointing device
movw %cs, %ax # aka SETUPSEG
subw $DELTA_INITSEG, %ax # aka INITSEG
@@ -740,6 +758,7 @@
A20_ENABLE_LOOPS = 255 # Total loops to try


+#ifndef CONFIG_VOYAGER
a20_try_loop:

# First, see if we are on a system with no A20 gate.
@@ -758,11 +777,14 @@
jnz a20_done

# Try enabling A20 through the keyboard controller
+#endif /* CONFIG_VOYAGER */
a20_kbc:
call empty_8042

+#ifndef CONFIG_VOYAGER
call a20_test # Just in case the BIOS worked
jnz a20_done # but had a delayed reaction.
+#endif

movb $0xD1, %al # command write
outb %al, $0x64
@@ -772,6 +794,7 @@
outb %al, $0x60
call empty_8042

+#ifndef CONFIG_VOYAGER
# Wait until a20 really *is* enabled; it can take a fair amount of
# time on certain systems; Toshiba Tecras are known to have this
# problem.
@@ -819,6 +842,7 @@
# If we get here, all is good
a20_done:

+#endif /* CONFIG_VOYAGER */
# set up gdt and idt
lidt idt_48 # load idt with 0,0
xorl %eax, %eax # Compute gdt_base
@@ -870,7 +894,7 @@
subw $DELTA_INITSEG, %si
shll $4, %esi # Convert to 32-bit pointer
# NOTE: For high loaded big kernels we need a
-# jmpi 0x100000,__KERNEL_CS
+# jmpi 0x100000,__BOOT_CS
#
# but we yet haven't reloaded the CS register, so the default size
# of the target offset still is 16 bit.
@@ -881,7 +905,7 @@
.byte 0x66, 0xea # prefix + jmpi-opcode
code32: .long 0x1000 # will be set to 0x100000
# for big kernels
- .word __KERNEL_CS
+ .word __BOOT_CS

# Here's a bunch of information about your current kernel..
kernel_version: .ascii UTS_RELEASE
@@ -985,6 +1009,7 @@
.string "INT15 refuses to access high mem, giving up."


+#ifndef CONFIG_VOYAGER
# This routine tests whether or not A20 is enabled. If so, it
# exits with zf = 0.
#
@@ -1015,6 +1040,8 @@
popw %cx
ret

+#endif /* CONFIG_VOYAGER */
+
# This routine checks that the keyboard command queue is empty
# (after emptying the output buffers)
#
@@ -1075,13 +1102,19 @@

# Descriptor tables
#
-# NOTE: if you think the GDT is large, you can make it smaller by just
-# defining the KERNEL_CS and KERNEL_DS entries and shifting the gdt
-# address down by GDT_ENTRY_KERNEL_CS*8. This puts bogus entries into
-# the GDT, but those wont be used so it's not a problem.
+# NOTE: The intel manual says gdt should be sixteen bytes aligned for
+# efficiency reasons. However, there are machines which are known not
+# to boot with misaligned GDTs, so alter this at your peril! If you alter
+# GDT_ENTRY_BOOT_CS (in asm/segment.h) remember to leave at least two
+# empty GDT entries (one for NULL and one reserved).
+#
+# NOTE: On some CPUs, the GDT must be 8 byte aligned. This is
+# true for the Voyager Quad CPU card which will not boot without
+# This directive. 16 byte aligment is recommended by intel.
#
+ .align 16
gdt:
- .fill GDT_ENTRY_KERNEL_CS,8,0
+ .fill GDT_ENTRY_BOOT_CS,8,0

.word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 # base address = 0
@@ -1094,12 +1127,17 @@
.word 0x9200 # data read/write
.word 0x00CF # granularity = 4096, 386
# (+5th nibble of limit)
+gdt_end:
+ .align 4
+
+ .word 0 # alignment byte
idt_48:
.word 0 # idt limit = 0
.word 0, 0 # idt base = 0L
-gdt_48:
- .word GDT_ENTRY_KERNEL_CS*8 + 16 - 1 # gdt limit

+ .word 0 # alignment byte
+gdt_48:
+ .word gdt_end - gdt - 1 # gdt limit
.word 0, 0 # gdt base (filled in later)

# Include video setup & detection code
diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
--- a/arch/i386/kernel/Makefile Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/Makefile Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
--- a/arch/i386/kernel/cpu/common.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/cpu/common.c Tue Nov 12 16:36:44 2002
@@ -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;
diff -Nru a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
--- a/arch/i386/kernel/head.S Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/head.S Tue Nov 12 16:36:44 2002
@@ -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 */
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/irq.c Tue Nov 12 16:36:44 2002
@@ -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))
diff -Nru a/arch/i386/kernel/timers/Makefile b/arch/i386/kernel/timers/Makefile
--- a/arch/i386/kernel/timers/Makefile Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/timers/Makefile Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/arch/i386/kernel/timers/timer.c b/arch/i386/kernel/timers/timer.c
--- a/arch/i386/kernel/timers/timer.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/timers/timer.c Tue Nov 12 16:36:44 2002
@@ -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,
-#endif
NULL,
};

diff -Nru a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c
--- a/arch/i386/kernel/timers/timer_pit.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/timers/timer_pit.c Tue Nov 12 16:36:44 2002
@@ -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;
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/timers/timer_tsc.c Tue Nov 12 16:36:44 2002
@@ -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);
+
+

/************************************************************/

diff -Nru a/arch/i386/kernel/trampoline.S b/arch/i386/kernel/trampoline.S
--- a/arch/i386/kernel/trampoline.S Tue Nov 12 16:36:44 2002
+++ b/arch/i386/kernel/trampoline.S Tue Nov 12 16:36:44 2002
@@ -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:
diff -Nru a/arch/i386/mach-voyager/setup.c b/arch/i386/mach-voyager/setup.c
--- a/arch/i386/mach-voyager/setup.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/mach-voyager/setup.c Tue Nov 12 16:36:44 2002
@@ -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)
diff -Nru a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c
--- a/arch/i386/mach-voyager/voyager_basic.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/mach-voyager/voyager_basic.c Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c
--- a/arch/i386/mach-voyager/voyager_smp.c Tue Nov 12 16:36:44 2002
+++ b/arch/i386/mach-voyager/voyager_smp.c Tue Nov 12 16:36:44 2002
@@ -50,11 +50,6 @@
* indexed physically */
struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;

-/* Per CPU interrupt stacks */
-extern union thread_union init_irq_union;
-union thread_union *irq_stacks[NR_CPUS] __cacheline_aligned =
- { &init_irq_union, };
-
/* physical ID of the CPU used to boot the system */
unsigned char boot_cpu_id;

@@ -450,6 +445,7 @@
struct cpuinfo_x86 *c=&cpu_data[id];

*c = boot_cpu_data;
+
identify_cpu(c);
}

@@ -512,6 +508,11 @@
/* if we're a quad, we may need to bootstrap other CPUs */
do_quad_bootstrap();

+ /* FIXME: this is rather a poor hack to prevent the CPU
+ * activating softirqs while it's supposed to be waiting for
+ * permission to proceed. Without this, the new per CPU stuff
+ * in the softirqs will fail */
+ local_irq_disable();
set_bit(cpuid, &cpu_callin_map);

/* signal that we're done */
@@ -519,6 +520,7 @@

while (!test_bit(cpuid, &smp_commenced_mask))
rep_nop();
+ local_irq_enable();

local_flush_tlb();

@@ -537,28 +539,6 @@
}


-static void __init setup_irq_stack(struct task_struct *p, int cpu)
-{
- unsigned long stk;
-
- stk = __get_free_pages(GFP_KERNEL, THREAD_ORDER+1);
- if (!stk)
- panic("I can't seem to allocate my irq stack. Oh well, giving up.");
-
- irq_stacks[cpu] = (void *)stk;
- memset(irq_stacks[cpu], 0, THREAD_SIZE);
- irq_stacks[cpu]->thread_info.cpu = cpu;
- irq_stacks[cpu]->thread_info.preempt_count = 1;
- /* interrupts are not preemptable */
- p->thread_info->irq_stack = irq_stacks[cpu];
-
- /* If we want to make the irq stack more than one unit
- * deep, we can chain then off of the irq_stack pointer
- * here.
- */
-}
-
-
/* Routine to kick start the given CPU and wait for it to report ready
* (or timeout in startup). When this routine returns, the requested
* CPU is either fully running and configured or known to be dead.
@@ -617,20 +597,17 @@
if(IS_ERR(idle))
panic("failed fork for CPU%d", cpu);

- setup_irq_stack(idle, cpu);
-
init_idle(idle, cpu);

idle->thread.eip = (unsigned long) start_secondary;
unhash_process(idle);
-
- /* The -4 is to correct for the fact that the stack pointer
- * is used to find the location of the thread_info structure
- * by masking off several of the LSBs. Without the -4, esp
- * is pointing to the page after the one the stack is on.
- */
- stack_start.esp = (void *)(THREAD_SIZE - 4 + (char *)idle->thread_info);
-
+ /* init_tasks (in sched.c) is indexed logically */
+#if 0
+ // for AC kernels
+ stack_start.esp = (THREAD_SIZE + (__u8 *)TSK_TO_KSTACK(idle));
+#else
+ stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle->thread_info);
+#endif
/* Note: Don't modify initial ss override */
VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
(unsigned long)hijack_source.val, hijack_source.idt.Segment,
@@ -764,6 +741,9 @@

/* enable our own CPIs */
vic_enable_cpi();
+
+ set_bit(boot_cpu_id, &cpu_online_map);
+ set_bit(boot_cpu_id, &cpu_callout_map);

/* loop over all the extended VIC CPUs and boot them. The
* Quad CPUs must be bootstrapped by their extended VIC cpu */
@@ -1312,12 +1292,9 @@
static inline void
wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
{
- __u8 cpu = smp_processor_id();
-
irq_enter();
smp_local_timer_interrupt(regs);
irq_exit();
-
}

/* local (per CPU) timer interrupt. It does both profiling and
diff -Nru a/drivers/char/sysrq.c b/drivers/char/sysrq.c
--- a/drivers/char/sysrq.c Tue Nov 12 16:36:44 2002
+++ b/drivers/char/sysrq.c Tue Nov 12 16:36:44 2002
@@ -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,
diff -Nru a/include/asm-i386/desc.h b/include/asm-i386/desc.h
--- a/include/asm-i386/desc.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/desc.h Tue Nov 12 16:36:44 2002
@@ -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];
diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
--- a/include/asm-i386/hw_irq.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/hw_irq.h Tue Nov 12 16:36:44 2002
@@ -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));
diff -Nru a/include/asm-i386/processor.h b/include/asm-i386/processor.h
--- a/include/asm-i386/processor.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/processor.h Tue Nov 12 16:36:44 2002
@@ -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;
};
diff -Nru a/include/asm-i386/segment.h b/include/asm-i386/segment.h
--- a/include/asm-i386/segment.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/segment.h Tue Nov 12 16:36:44 2002
@@ -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
diff -Nru a/include/asm-i386/smp.h b/include/asm-i386/smp.h
--- a/include/asm-i386/smp.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/smp.h Tue Nov 12 16:36:44 2002
@@ -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 __inline int 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 */
diff -Nru a/include/asm-i386/voyager.h b/include/asm-i386/voyager.h
--- a/include/asm-i386/voyager.h Tue Nov 12 16:36:44 2002
+++ b/include/asm-i386/voyager.h Tue Nov 12 16:36:44 2002
@@ -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);

--==_Exmh_-5923708860--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/