Commit 85fe9359 authored by James Bottomley's avatar James Bottomley

Enable Voyager in current kernel

parent 58acbf38
......@@ -38,6 +38,33 @@ source "init/Kconfig"
menu "Processor type and features"
choice
prompt "Subarchitecture Type"
default PC
config PC
bool PC
help
Choose this option if your computer is a standard PC or compatible.
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.
# Visual Workstation support is utterly broken.
# If you want to see it working mail an VW540 to hch@infradead.org 8)
#bool 'SGI Visual Workstation support' CONFIG_VISWS
endchoice
choice
prompt "Processor family"
default M686
......@@ -337,6 +364,7 @@ config PREEMPT
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
......@@ -690,6 +718,7 @@ endmenu
menu "Power management options (ACPI, APM)"
depends on !VOYAGER
config PM
bool "Power Management support"
......@@ -990,9 +1019,6 @@ endmenu
menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
# Visual Workstation support is utterly broken.
# If you want to see it working mail an VW540 to hch@infradead.org 8)
#bool 'SGI Visual Workstation support' CONFIG_VISWS
config X86_VISWS_APIC
bool
depends on VISWS
......@@ -1000,11 +1026,12 @@ config X86_VISWS_APIC
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
......@@ -1019,7 +1046,7 @@ config PCI
config X86_IO_APIC
bool
depends on !VISWS && SMP
depends on !VISWS && SMP && !VOYAGER
default y
choice
......@@ -1063,6 +1090,7 @@ config PCI_DIRECT
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.
......@@ -1076,6 +1104,7 @@ source "drivers/pci/Kconfig"
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
......@@ -1101,13 +1130,17 @@ config EISA
config MCA
bool "MCA support"
depends on !VISWS
depends on !VISWS && !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
<file:Documentation/mca.txt> (and especially the web page given
there) before attempting to build an MCA bus kernel.
config MCA
depends on VOYAGER
default y if VOYAGER
source "drivers/mca/Kconfig"
config HOTPLUG
......@@ -1574,12 +1607,12 @@ config FRAME_POINTER
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
......@@ -1597,15 +1630,16 @@ source "lib/Kconfig"
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
......@@ -51,6 +51,10 @@ CFLAGS += $(cflags-y)
#default subarch .c files
mcore-y := mach-default
#Voyager subarch support
mflags-$(CONFIG_VOYAGER) := -Iinclude/asm-i386/mach-voyager
mcore-$(CONFIG_VOYAGER) := mach-voyager
#VISWS subarch support
mflags-$(CONFIG_VISWS) := -Iinclude/asm-i386/mach-visws
mcore-$(CONFIG_VISWS) := mach-visws
......
......@@ -476,6 +476,24 @@ sysdesc_ok:
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_TEST_LOOPS = 32 # Iterations per wait
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 @@ a20_bios:
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 @@ a20_kbc:
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 @@ a20_err_msg:
# 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
......@@ -985,6 +1009,7 @@ bootsect_panic_mess:
.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 @@ a20_test_wait:
popw %cx
ret
#endif /* CONFIG_VOYAGER */
# This routine checks that the keyboard command queue is empty
# (after emptying the output buffers)
#
......
......@@ -50,11 +50,6 @@ int smp_threads_ready = 0;
* 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 @@ smp_store_cpu_info(int id)
struct cpuinfo_x86 *c=&cpu_data[id];
*c = boot_cpu_data;
identify_cpu(c);
}
......@@ -512,6 +508,11 @@ start_secondary(void *unused)
/* 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 @@ start_secondary(void *unused)
while (!test_bit(cpuid, &smp_commenced_mask))
rep_nop();
local_irq_enable();
local_flush_tlb();
......@@ -533,29 +535,7 @@ fork_by_hand(void)
struct pt_regs regs;
/* don't care about the eip and regs settings since we'll
* never reschedule the forked task. */
return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL);
}
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.
*/
return do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0, NULL, NULL);
}
......@@ -617,20 +597,17 @@ do_boot_cpu(__u8 cpu)
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,
......@@ -765,6 +742,9 @@ smp_boot_cpus(void)
/* 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 */
for(i = 0; i < NR_CPUS; i++) {
......@@ -1312,12 +1292,9 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
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
......
......@@ -131,7 +131,7 @@ static inline int unregister_profile_notifier(struct notifier_block * nb)
#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));
......
......@@ -6,6 +6,7 @@
*/
#ifndef __ASSEMBLY__
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/threads.h>
#endif
......@@ -83,11 +84,22 @@ extern volatile unsigned long cpu_callout_map;
#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 @@ extern inline int any_online_cpu(unsigned int mask)
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 @@ static __inline int logical_smp_processor_id(void)
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment