Commit 6c82a000 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'x86/generalize-visws' into x86/core

parents 5b4d2386 39415a44
...@@ -181,12 +181,12 @@ config X86_64_SMP ...@@ -181,12 +181,12 @@ config X86_64_SMP
config X86_HT config X86_HT
bool bool
depends on SMP depends on SMP
depends on (X86_32 && !(X86_VISWS || X86_VOYAGER)) || X86_64 depends on (X86_32 && !X86_VOYAGER) || X86_64
default y default y
config X86_BIOS_REBOOT config X86_BIOS_REBOOT
bool bool
depends on !X86_VISWS && !X86_VOYAGER depends on !X86_VOYAGER
default y default y
config X86_TRAMPOLINE config X86_TRAMPOLINE
...@@ -232,13 +232,13 @@ config SMP ...@@ -232,13 +232,13 @@ config SMP
config X86_FIND_SMP_CONFIG config X86_FIND_SMP_CONFIG
def_bool y def_bool y
depends on X86_MPPARSE || X86_VOYAGER || X86_VISWS depends on X86_MPPARSE || X86_VOYAGER
if ACPI if ACPI
config X86_MPPARSE config X86_MPPARSE
def_bool y def_bool y
bool "Enable MPS table" bool "Enable MPS table"
depends on X86_LOCAL_APIC && !X86_VISWS depends on X86_LOCAL_APIC
help help
For old smp systems that do not have proper acpi support. Newer systems For old smp systems that do not have proper acpi support. Newer systems
(esp with 64bit cpus) with acpi support, MADT and DSDT will override it (esp with 64bit cpus) with acpi support, MADT and DSDT will override it
...@@ -247,7 +247,7 @@ endif ...@@ -247,7 +247,7 @@ endif
if !ACPI if !ACPI
config X86_MPPARSE config X86_MPPARSE
def_bool y def_bool y
depends on X86_LOCAL_APIC && !X86_VISWS depends on X86_LOCAL_APIC
endif endif
choice choice
...@@ -281,18 +281,6 @@ config X86_VOYAGER ...@@ -281,18 +281,6 @@ config X86_VOYAGER
If you do not specifically know you have a Voyager based machine, If you do not specifically know you have a Voyager based machine,
say N here, otherwise the kernel you build will not be bootable. say N here, otherwise the kernel you build will not be bootable.
config X86_VISWS
bool "SGI 320/540 (Visual Workstation)"
depends on X86_32 && PCI
help
The SGI Visual Workstation series is an IA32-based workstation
based on SGI systems chips with some legacy PC hardware attached.
Say Y here to create a kernel to run on the SGI 320 or 540.
A kernel compiled for the Visual Workstation will not run on PCs
and vice versa. See <file:Documentation/sgi-visws.txt> for details.
config X86_GENERICARCH config X86_GENERICARCH
bool "Generic architecture" bool "Generic architecture"
depends on X86_32 depends on X86_32
...@@ -363,6 +351,18 @@ config X86_VSMP ...@@ -363,6 +351,18 @@ config X86_VSMP
endchoice endchoice
config X86_VISWS
bool "SGI 320/540 (Visual Workstation)"
depends on X86_32 && PCI && !X86_VOYAGER && X86_MPPARSE && PCI_GODIRECT
help
The SGI Visual Workstation series is an IA32-based workstation
based on SGI systems chips with some legacy PC hardware attached.
Say Y here to create a kernel to run on the SGI 320 or 540.
A kernel compiled for the Visual Workstation will run on general
PCs as well. See <file:Documentation/sgi-visws.txt> for details.
config SCHED_NO_NO_OMIT_FRAME_POINTER config SCHED_NO_NO_OMIT_FRAME_POINTER
def_bool y def_bool y
prompt "Single-depth WCHAN output" prompt "Single-depth WCHAN output"
...@@ -391,7 +391,7 @@ config VMI ...@@ -391,7 +391,7 @@ config VMI
bool "VMI Guest support" bool "VMI Guest support"
select PARAVIRT select PARAVIRT
depends on X86_32 depends on X86_32
depends on !(X86_VISWS || X86_VOYAGER) depends on !X86_VOYAGER
help help
VMI provides a paravirtualized interface to the VMware ESX server VMI provides a paravirtualized interface to the VMware ESX server
(it could be used by other hypervisors in theory too, but is not (it could be used by other hypervisors in theory too, but is not
...@@ -402,7 +402,7 @@ config KVM_CLOCK ...@@ -402,7 +402,7 @@ config KVM_CLOCK
bool "KVM paravirtualized clock" bool "KVM paravirtualized clock"
select PARAVIRT select PARAVIRT
select PARAVIRT_CLOCK select PARAVIRT_CLOCK
depends on !(X86_VISWS || X86_VOYAGER) depends on !X86_VOYAGER
help help
Turning on this option will allow you to run a paravirtualized clock Turning on this option will allow you to run a paravirtualized clock
when running over the KVM hypervisor. Instead of relying on a PIT when running over the KVM hypervisor. Instead of relying on a PIT
...@@ -413,7 +413,7 @@ config KVM_CLOCK ...@@ -413,7 +413,7 @@ config KVM_CLOCK
config KVM_GUEST config KVM_GUEST
bool "KVM Guest support" bool "KVM Guest support"
select PARAVIRT select PARAVIRT
depends on !(X86_VISWS || X86_VOYAGER) depends on !X86_VOYAGER
help help
This option enables various optimizations for running under the KVM This option enables various optimizations for running under the KVM
hypervisor. hypervisor.
...@@ -422,7 +422,7 @@ source "arch/x86/lguest/Kconfig" ...@@ -422,7 +422,7 @@ source "arch/x86/lguest/Kconfig"
config PARAVIRT config PARAVIRT
bool "Enable paravirtualization code" bool "Enable paravirtualization code"
depends on !(X86_VISWS || X86_VOYAGER) depends on !X86_VOYAGER
help help
This changes the kernel so it can modify itself when it is run This changes the kernel so it can modify itself when it is run
under a hypervisor, potentially improving performance significantly under a hypervisor, potentially improving performance significantly
...@@ -628,7 +628,7 @@ source "kernel/Kconfig.preempt" ...@@ -628,7 +628,7 @@ source "kernel/Kconfig.preempt"
config X86_UP_APIC config X86_UP_APIC
bool "Local APIC support on uniprocessors" bool "Local APIC support on uniprocessors"
depends on X86_32 && !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) depends on X86_32 && !SMP && !(X86_VOYAGER || X86_GENERICARCH)
help help
A local APIC (Advanced Programmable Interrupt Controller) is an A local APIC (Advanced Programmable Interrupt Controller) is an
integrated interrupt controller in the CPU. If you have a single-CPU integrated interrupt controller in the CPU. If you have a single-CPU
...@@ -653,11 +653,11 @@ config X86_UP_IOAPIC ...@@ -653,11 +653,11 @@ config X86_UP_IOAPIC
config X86_LOCAL_APIC config X86_LOCAL_APIC
def_bool y def_bool y
depends on X86_64 || (X86_32 && (X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH)) depends on X86_64 || (X86_32 && (X86_UP_APIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
config X86_IO_APIC config X86_IO_APIC
def_bool y def_bool y
depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH)) depends on X86_64 || (X86_32 && (X86_UP_IOAPIC || (SMP && !X86_VOYAGER) || X86_GENERICARCH))
config X86_VISWS_APIC config X86_VISWS_APIC
def_bool y def_bool y
...@@ -711,7 +711,7 @@ config X86_MCE_NONFATAL ...@@ -711,7 +711,7 @@ config X86_MCE_NONFATAL
config X86_MCE_P4THERMAL config X86_MCE_P4THERMAL
bool "check for P4 thermal throttling interrupt." bool "check for P4 thermal throttling interrupt."
depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP) && !X86_VISWS depends on X86_32 && X86_MCE && (X86_UP_APIC || SMP)
help help
Enabling this feature will cause a message to be printed when the P4 Enabling this feature will cause a message to be printed when the P4
enters thermal throttling. enters thermal throttling.
...@@ -1414,7 +1414,7 @@ config X86_APM_BOOT ...@@ -1414,7 +1414,7 @@ config X86_APM_BOOT
menuconfig APM menuconfig APM
tristate "APM (Advanced Power Management) BIOS support" tristate "APM (Advanced Power Management) BIOS support"
depends on X86_32 && PM_SLEEP && !X86_VISWS depends on X86_32 && PM_SLEEP
---help--- ---help---
APM is a BIOS specification for saving power using several different APM is a BIOS specification for saving power using several different
techniques. This is mostly useful for battery powered laptops with techniques. This is mostly useful for battery powered laptops with
...@@ -1561,7 +1561,7 @@ config PCI ...@@ -1561,7 +1561,7 @@ config PCI
choice choice
prompt "PCI access mode" prompt "PCI access mode"
depends on X86_32 && PCI && !X86_VISWS depends on X86_32 && PCI
default PCI_GOANY default PCI_GOANY
---help--- ---help---
On PCI systems, the BIOS can be used to detect the PCI devices and On PCI systems, the BIOS can be used to detect the PCI devices and
...@@ -1598,12 +1598,12 @@ endchoice ...@@ -1598,12 +1598,12 @@ endchoice
config PCI_BIOS config PCI_BIOS
def_bool y def_bool y
depends on X86_32 && !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY) depends on X86_32 && PCI && (PCI_GOBIOS || PCI_GOANY)
# x86-64 doesn't support PCI BIOS access from long mode so always go direct. # x86-64 doesn't support PCI BIOS access from long mode so always go direct.
config PCI_DIRECT config PCI_DIRECT
def_bool y def_bool y
depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC) || X86_VISWS) depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC))
config PCI_MMCONFIG config PCI_MMCONFIG
def_bool y def_bool y
...@@ -1663,7 +1663,7 @@ if X86_32 ...@@ -1663,7 +1663,7 @@ if X86_32
config ISA config ISA
bool "ISA support" bool "ISA support"
depends on !(X86_VOYAGER || X86_VISWS) depends on !X86_VOYAGER
help help
Find out whether you have ISA slots on your motherboard. ISA is the 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 name of a bus system, i.e. the way the CPU talks to the other stuff
...@@ -1690,7 +1690,7 @@ config EISA ...@@ -1690,7 +1690,7 @@ config EISA
source "drivers/eisa/Kconfig" source "drivers/eisa/Kconfig"
config MCA config MCA
bool "MCA support" if !(X86_VISWS || X86_VOYAGER) bool "MCA support" if !X86_VOYAGER
default y if X86_VOYAGER default y if X86_VOYAGER
help help
MicroChannel Architecture is found in some IBM PS/2 machines and MicroChannel Architecture is found in some IBM PS/2 machines and
......
...@@ -113,10 +113,6 @@ mcore-y := arch/x86/mach-default/ ...@@ -113,10 +113,6 @@ mcore-y := arch/x86/mach-default/
mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager mflags-$(CONFIG_X86_VOYAGER) := -Iinclude/asm-x86/mach-voyager
mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/ mcore-$(CONFIG_X86_VOYAGER) := arch/x86/mach-voyager/
# VISWS subarch support
mflags-$(CONFIG_X86_VISWS) := -Iinclude/asm-x86/mach-visws
mcore-$(CONFIG_X86_VISWS) := arch/x86/mach-visws/
# generic subarchitecture # generic subarchitecture
mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic mflags-$(CONFIG_X86_GENERICARCH):= -Iinclude/asm-x86/mach-generic
fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/ fcore-$(CONFIG_X86_GENERICARCH) += arch/x86/mach-generic/
......
...@@ -19,6 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o ...@@ -19,6 +19,7 @@ obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
obj-y += traps_$(BITS).o irq_$(BITS).o obj-y += traps_$(BITS).o irq_$(BITS).o
obj-y += time_$(BITS).o ioport.o ldt.o obj-y += time_$(BITS).o ioport.o ldt.o
obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
obj-$(CONFIG_X86_32) += probe_roms_32.o obj-$(CONFIG_X86_32) += probe_roms_32.o
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
......
...@@ -974,7 +974,7 @@ void __cpuinit setup_local_APIC(void) ...@@ -974,7 +974,7 @@ void __cpuinit setup_local_APIC(void)
* Double-check whether this APIC is really registered. * Double-check whether this APIC is really registered.
*/ */
if (!apic_id_registered()) if (!apic_id_registered())
BUG(); WARN_ON_ONCE(1);
/* /*
* Intel recommends to set DFR, LDR and TPR before enabling * Intel recommends to set DFR, LDR and TPR before enabling
......
...@@ -1313,6 +1313,11 @@ void __init e820_reserve_resources(void) ...@@ -1313,6 +1313,11 @@ void __init e820_reserve_resources(void)
} }
} }
/*
* Non-standard memory setup can be specified via this quirk:
*/
char * (*arch_memory_setup_quirk)(void);
char *__init default_machine_specific_memory_setup(void) char *__init default_machine_specific_memory_setup(void)
{ {
char *who = "BIOS-e820"; char *who = "BIOS-e820";
...@@ -1353,6 +1358,12 @@ char *__init default_machine_specific_memory_setup(void) ...@@ -1353,6 +1358,12 @@ char *__init default_machine_specific_memory_setup(void)
char *__init __attribute__((weak)) machine_specific_memory_setup(void) char *__init __attribute__((weak)) machine_specific_memory_setup(void)
{ {
if (arch_memory_setup_quirk) {
char *who = arch_memory_setup_quirk();
if (who)
return who;
}
return default_machine_specific_memory_setup(); return default_machine_specific_memory_setup();
} }
......
...@@ -725,13 +725,23 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) ...@@ -725,13 +725,23 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
static struct intel_mp_floating *mpf_found; static struct intel_mp_floating *mpf_found;
/*
* Machine specific quirk for finding the SMP config before other setup
* activities destroy the table:
*/
int (*mach_get_smp_config_quirk)(unsigned int early);
/* /*
* Scan the memory blocks for an SMP configuration block. * Scan the memory blocks for an SMP configuration block.
*/ */
static void __init __get_smp_config(unsigned early) static void __init __get_smp_config(unsigned int early)
{ {
struct intel_mp_floating *mpf = mpf_found; struct intel_mp_floating *mpf = mpf_found;
if (mach_get_smp_config_quirk) {
if (mach_get_smp_config_quirk(early))
return;
}
if (acpi_lapic && early) if (acpi_lapic && early)
return; return;
/* /*
...@@ -889,10 +899,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, ...@@ -889,10 +899,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
return 0; return 0;
} }
static void __init __find_smp_config(unsigned reserve) int (*mach_find_smp_config_quirk)(unsigned int reserve);
static void __init __find_smp_config(unsigned int reserve)
{ {
unsigned int address; unsigned int address;
if (mach_find_smp_config_quirk) {
if (mach_find_smp_config_quirk(reserve))
return;
}
/* /*
* FIXME: Linux assumes you have 640K of base ram.. * FIXME: Linux assumes you have 640K of base ram..
* this continues the error... * this continues the error...
......
...@@ -596,6 +596,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -596,6 +596,7 @@ void __init setup_arch(char **cmdline_p)
{ {
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
visws_early_detect();
pre_setup_arch_hook(); pre_setup_arch_hook();
early_cpu_init(); early_cpu_init();
#else #else
......
...@@ -3,7 +3,7 @@ config LGUEST_GUEST ...@@ -3,7 +3,7 @@ config LGUEST_GUEST
select PARAVIRT select PARAVIRT
depends on X86_32 depends on X86_32
depends on !X86_PAE depends on !X86_PAE
depends on !(X86_VISWS || X86_VOYAGER) depends on !X86_VOYAGER
select VIRTIO select VIRTIO
select VIRTIO_RING select VIRTIO_RING
select VIRTIO_CONSOLE select VIRTIO_CONSOLE
......
...@@ -10,6 +10,14 @@ ...@@ -10,6 +10,14 @@
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/setup.h> #include <asm/setup.h>
/*
* Any quirks to be performed to initialize timers/irqs/etc?
*/
int (*arch_time_init_quirk)(void);
int (*arch_pre_intr_init_quirk)(void);
int (*arch_intr_init_quirk)(void);
int (*arch_trap_init_quirk)(void);
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
#define DEFAULT_SEND_IPI (1) #define DEFAULT_SEND_IPI (1)
#else #else
...@@ -29,6 +37,10 @@ int no_broadcast=DEFAULT_SEND_IPI; ...@@ -29,6 +37,10 @@ int no_broadcast=DEFAULT_SEND_IPI;
**/ **/
void __init pre_intr_init_hook(void) void __init pre_intr_init_hook(void)
{ {
if (arch_pre_intr_init_quirk) {
if (arch_pre_intr_init_quirk())
return;
}
init_ISA_irqs(); init_ISA_irqs();
} }
...@@ -52,6 +64,10 @@ static struct irqaction irq2 = { ...@@ -52,6 +64,10 @@ static struct irqaction irq2 = {
**/ **/
void __init intr_init_hook(void) void __init intr_init_hook(void)
{ {
if (arch_intr_init_quirk) {
if (arch_intr_init_quirk())
return;
}
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
apic_intr_init(); apic_intr_init();
#endif #endif
...@@ -65,7 +81,7 @@ void __init intr_init_hook(void) ...@@ -65,7 +81,7 @@ void __init intr_init_hook(void)
* *
* Description: * Description:
* generally used to activate any machine specific identification * generally used to activate any machine specific identification
* routines that may be needed before setup_arch() runs. On VISWS * routines that may be needed before setup_arch() runs. On Voyager
* this is used to get the board revision and type. * this is used to get the board revision and type.
**/ **/
void __init pre_setup_arch_hook(void) void __init pre_setup_arch_hook(void)
...@@ -81,6 +97,10 @@ void __init pre_setup_arch_hook(void) ...@@ -81,6 +97,10 @@ void __init pre_setup_arch_hook(void)
**/ **/
void __init trap_init_hook(void) void __init trap_init_hook(void)
{ {
if (arch_trap_init_quirk) {
if (arch_trap_init_quirk())
return;
}
} }
static struct irqaction irq0 = { static struct irqaction irq0 = {
...@@ -99,6 +119,16 @@ static struct irqaction irq0 = { ...@@ -99,6 +119,16 @@ static struct irqaction irq0 = {
**/ **/
void __init time_init_hook(void) void __init time_init_hook(void)
{ {
if (arch_time_init_quirk) {
/*
* A nonzero return code does not mean failure, it means
* that the architecture quirk does not want any
* generic (timer) setup to be performed after this:
*/
if (arch_time_init_quirk())
return;
}
irq0.mask = cpumask_of_cpu(0); irq0.mask = cpumask_of_cpu(0);
setup_irq(0, &irq0); setup_irq(0, &irq0);
} }
......
#
# Makefile for the linux kernel.
#
obj-y := setup.o traps.o reboot.o
obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o
obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o
#include <linux/init.h>
#include <linux/smp.h>
#include <asm/smp.h>
#include <asm/io.h>
#include "cobalt.h"
#include "mach_apic.h"
extern unsigned int __cpuinitdata maxcpus;
/*
* The Visual Workstation is Intel MP compliant in the hardware
* sense, but it doesn't have a BIOS(-configuration table).
* No problem for Linux.
*/
static void __init MP_processor_info (struct mpc_config_processor *m)
{
int ver, logical_apicid;
physid_mask_t apic_cpus;
if (!(m->mpc_cpuflag & CPU_ENABLED))
return;
logical_apicid = m->mpc_apicid;
printk(KERN_INFO "%sCPU #%d %u:%u APIC version %d\n",
m->mpc_cpuflag & CPU_BOOTPROCESSOR ? "Bootup " : "",
m->mpc_apicid,
(m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8,
(m->mpc_cpufeature & CPU_MODEL_MASK) >> 4,
m->mpc_apicver);
if (m->mpc_cpuflag & CPU_BOOTPROCESSOR)
boot_cpu_physical_apicid = m->mpc_apicid;
ver = m->mpc_apicver;
if ((ver >= 0x14 && m->mpc_apicid >= 0xff) || m->mpc_apicid >= 0xf) {
printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
m->mpc_apicid, MAX_APICS);
return;
}
apic_cpus = apicid_to_cpu_present(m->mpc_apicid);
physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
/*
* Validate version
*/
if (ver == 0x0) {
printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! "
"fixing up to 0x10. (tell your hw vendor)\n",
m->mpc_apicid);
ver = 0x10;
}
apic_version[m->mpc_apicid] = ver;
}
void __init find_smp_config(void)
{
struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
if (ncpus > CO_CPU_MAX) {
printk(KERN_WARNING "find_visws_smp: got cpu count of %d at %p\n",
ncpus, mp);
ncpus = CO_CPU_MAX;
}
if (ncpus > maxcpus)
ncpus = maxcpus;
#ifdef CONFIG_X86_LOCAL_APIC
smp_found_config = 1;
#endif
while (ncpus--)
MP_processor_info(mp++);
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
}
void __init get_smp_config (void)
{
}
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/delay.h>
#include <asm/io.h>
#include "piix4.h"
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
void machine_shutdown(void)
{
#ifdef CONFIG_SMP
smp_send_stop();
#endif
}
void machine_emergency_restart(void)
{
/*
* Visual Workstations restart after this
* register is poked on the PIIX4
*/
outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
}
void machine_restart(char * __unused)
{
machine_shutdown();
machine_emergency_restart();
}
void machine_power_off(void)
{
unsigned short pm_status;
extern unsigned int pci_bus0;
while ((pm_status = inw(PMSTS_PORT)) & 0x100)
outw(pm_status, PMSTS_PORT);
outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
mdelay(10);
#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
(0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
outl(PCI_CONF1_ADDRESS(pci_bus0, SPECIAL_DEV, SPECIAL_REG), 0xCF8);
outl(PIIX_SPECIAL_STOP, 0xCFC);
}
void machine_halt(void)
{
}
/*
* Unmaintained SGI Visual Workstation support.
* Split out from setup.c by davej@suse.de
*/
#include <linux/smp.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/fixmap.h>
#include <asm/arch_hooks.h>
#include <asm/io.h>
#include <asm/e820.h>
#include <asm/setup.h>
#include "cobalt.h"
#include "piix4.h"
int no_broadcast;
char visws_board_type = -1;
char visws_board_rev = -1;
void __init visws_get_board_type_and_rev(void)
{
int raw;
visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
>> PIIX_GPI_BD_SHIFT;
/*
* Get Board rev.
* First, we have to initialize the 307 part to allow us access
* 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_p(SIO_DEV_MSB, SIO_INDEX);
outb_p(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_p(SIO_DEV_ENB, SIO_INDEX);
outb_p(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_p(SIO_DEV_MSB, SIO_INDEX);
outb_p(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_p(SIO_DEV_ENB, SIO_INDEX);
outb_p(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);
/*
* Now, initialize the GPIO registers.
* We want them all to be inputs which is the
* power on default, so let's leave them alone.
* So, let's just read the board rev!
*/
raw = inb_p(SIO_GP_DATA1);
raw &= 0x7f; /* 7 bits of valid board revision ID. */
if (visws_board_type == VISWS_320) {
if (raw < 0x6) {
visws_board_rev = 4;
} else if (raw < 0xc) {
visws_board_rev = 5;
} else {
visws_board_rev = 6;
}
} else if (visws_board_type == VISWS_540) {
visws_board_rev = 2;
} else {
visws_board_rev = raw;
}
printk(KERN_INFO "Silicon Graphics Visual Workstation %s (rev %d) detected\n",
(visws_board_type == VISWS_320 ? "320" :
(visws_board_type == VISWS_540 ? "540" :
"unknown")), visws_board_rev);
}
void __init pre_intr_init_hook(void)
{
init_VISWS_APIC_irqs();
}
void __init intr_init_hook(void)
{
#ifdef CONFIG_X86_LOCAL_APIC
apic_intr_init();
#endif
}
void __init pre_setup_arch_hook()
{
visws_get_board_type_and_rev();
}
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED | IRQF_IRQPOLL,
.name = "timer",
};
void __init time_init_hook(void)
{
printk(KERN_INFO "Starting Cobalt Timer system clock\n");
/* Set the countdown value */
co_cpu_write(CO_CPU_TIMEVAL, CO_TIME_HZ/HZ);
/* Start the timer */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) | CO_CTRL_TIMERUN);
/* Enable (unmask) the timer interrupt */
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
/* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
setup_irq(0, &irq0);
}
/* Hook for machine specific memory setup. */
#define MB (1024 * 1024)
unsigned long sgivwfb_mem_phys;
unsigned long sgivwfb_mem_size;
EXPORT_SYMBOL(sgivwfb_mem_phys);
EXPORT_SYMBOL(sgivwfb_mem_size);
long long mem_size __initdata = 0;
char * __init machine_specific_memory_setup(void)
{
long long gfx_mem_size = 8 * MB;
mem_size = boot_params.alt_mem_k;
if (!mem_size) {
printk(KERN_WARNING "Bootloader didn't set memory size, upgrade it !\n");
mem_size = 128 * MB;
}
/*
* this hardcodes the graphics memory to 8 MB
* it really should be sized dynamically (or at least
* set as a boot param)
*/
if (!sgivwfb_mem_size) {
printk(KERN_WARNING "Defaulting to 8 MB framebuffer size\n");
sgivwfb_mem_size = 8 * MB;
}
/*
* Trim to nearest MB
*/
sgivwfb_mem_size &= ~((1 << 20) - 1);
sgivwfb_mem_phys = mem_size - gfx_mem_size;
e820_add_region(0, LOWMEMSIZE(), E820_RAM);
e820_add_region(HIGH_MEMORY, mem_size - sgivwfb_mem_size - HIGH_MEMORY, E820_RAM);
e820_add_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED);
return "PROM";
}
/* VISWS traps */
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <asm/io.h>
#include <asm/arch_hooks.h>
#include <asm/apic.h>
#include "cobalt.h"
#include "lithium.h"
#define A01234 (LI_INTA_0 | LI_INTA_1 | LI_INTA_2 | LI_INTA_3 | LI_INTA_4)
#define BCD (LI_INTB | LI_INTC | LI_INTD)
#define ALLDEVS (A01234 | BCD)
static __init void lithium_init(void)
{
set_fixmap(FIX_LI_PCIA, LI_PCI_A_PHYS);
set_fixmap(FIX_LI_PCIB, LI_PCI_B_PHYS);
if ((li_pcia_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
(li_pcia_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'A');
panic("This machine is not SGI Visual Workstation 320/540");
}
if ((li_pcib_read16(PCI_VENDOR_ID) != PCI_VENDOR_ID_SGI) ||
(li_pcib_read16(PCI_DEVICE_ID) != PCI_DEVICE_ID_SGI_LITHIUM)) {
printk(KERN_EMERG "Lithium hostbridge %c not found\n", 'B');
panic("This machine is not SGI Visual Workstation 320/540");
}
li_pcia_write16(LI_PCI_INTEN, ALLDEVS);
li_pcib_write16(LI_PCI_INTEN, ALLDEVS);
}
static __init void cobalt_init(void)
{
/*
* On normal SMP PC this is used only with SMP, but we have to
* use it and set it up here to start the Cobalt clock
*/
set_fixmap(FIX_APIC_BASE, APIC_DEFAULT_PHYS_BASE);
setup_local_APIC();
printk(KERN_INFO "Local APIC Version %#x, ID %#x\n",
(unsigned int)apic_read(APIC_LVR),
(unsigned int)apic_read(APIC_ID));
set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
set_fixmap(FIX_CO_APIC, CO_APIC_PHYS);
printk(KERN_INFO "Cobalt Revision %#lx, APIC ID %#lx\n",
co_cpu_read(CO_CPU_REV), co_apic_read(CO_APIC_ID));
/* Enable Cobalt APIC being careful to NOT change the ID! */
co_apic_write(CO_APIC_ID, co_apic_read(CO_APIC_ID) | CO_APIC_ENABLE);
printk(KERN_INFO "Cobalt APIC enabled: ID reg %#lx\n",
co_apic_read(CO_APIC_ID));
}
void __init trap_init_hook(void)
{
lithium_init();
cobalt_init();
}
...@@ -9,9 +9,7 @@ pci-y := fixup.o ...@@ -9,9 +9,7 @@ pci-y := fixup.o
pci-$(CONFIG_ACPI) += acpi.o pci-$(CONFIG_ACPI) += acpi.o
pci-y += legacy.o irq.o pci-y += legacy.o irq.o
# Careful: VISWS overrule the pci-y above. The colons are pci-$(CONFIG_X86_VISWS) += visws.o
# therefor correct. This needs a proper fix by distangling the code.
pci-$(CONFIG_X86_VISWS) := visws.o fixup.o
pci-$(CONFIG_X86_NUMAQ) += numa.o pci-$(CONFIG_X86_NUMAQ) += numa.o
......
...@@ -62,6 +62,11 @@ int __init pci_subsys_init(void) ...@@ -62,6 +62,11 @@ int __init pci_subsys_init(void)
#endif #endif
pci_legacy_init(); pci_legacy_init();
pcibios_irq_init(); pcibios_irq_init();
#ifdef CONFIG_X86_NUMAQ
pci_numa_init();
#endif
pcibios_init(); pcibios_init();
return 0;
} }
subsys_initcall(pci_subsys_init); subsys_initcall(pci_subsys_init);
...@@ -151,7 +151,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d) ...@@ -151,7 +151,7 @@ static void __devinit pci_fixup_i450nx(struct pci_dev *d)
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx);
static int __init pci_numa_init(void) int __init pci_numa_init(void)
{ {
int quad; int quad;
...@@ -176,11 +176,3 @@ static int __init pci_numa_init(void) ...@@ -176,11 +176,3 @@ static int __init pci_numa_init(void)
} }
return 0; return 0;
} }
static __init int pci_subsys_init(void)
{
pci_numa_init();
pcibios_irq_init();
pcibios_init();
}
subsys_initcall(pci_subsys_init);
...@@ -107,6 +107,7 @@ extern void __init dmi_check_skip_isa_align(void); ...@@ -107,6 +107,7 @@ extern void __init dmi_check_skip_isa_align(void);
/* some common used subsys_initcalls */ /* some common used subsys_initcalls */
extern int __init pci_acpi_init(void); extern int __init pci_acpi_init(void);
extern int __init pcibios_irq_init(void); extern int __init pcibios_irq_init(void);
extern int __init pci_numa_init(void);
extern int __init pcibios_init(void); extern int __init pcibios_init(void);
/* pci-mmconfig.c */ /* pci-mmconfig.c */
......
...@@ -8,18 +8,19 @@ ...@@ -8,18 +8,19 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
#include "cobalt.h" #include <asm/setup.h>
#include "lithium.h" #include <asm/visws/cobalt.h>
#include <asm/visws/lithium.h>
#include "pci.h" #include "pci.h"
static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; } static int pci_visws_enable_irq(struct pci_dev *dev) { return 0; }
static void pci_visws_disable_irq(struct pci_dev *dev) { } static void pci_visws_disable_irq(struct pci_dev *dev) { }
int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; /* int (*pcibios_enable_irq)(struct pci_dev *dev) = &pci_visws_enable_irq; */
void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; /* void (*pcibios_disable_irq)(struct pci_dev *dev) = &pci_visws_disable_irq; */
void __init pcibios_penalize_isa_irq(int irq, int active) {} /* void __init pcibios_penalize_isa_irq(int irq, int active) {} */
unsigned int pci_bus0, pci_bus1; unsigned int pci_bus0, pci_bus1;
...@@ -107,7 +108,15 @@ static int __init pci_visws_init(void) ...@@ -107,7 +108,15 @@ static int __init pci_visws_init(void)
static __init int pci_subsys_init(void) static __init int pci_subsys_init(void)
{ {
if (!is_visws_box())
return -1;
pcibios_enable_irq = &pci_visws_enable_irq;
pcibios_disable_irq = &pci_visws_disable_irq;
pci_visws_init(); pci_visws_init();
pcibios_init(); pcibios_init();
return 0;
} }
subsys_initcall(pci_subsys_init); subsys_initcall(pci_subsys_init);
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
menuconfig ACPI menuconfig ACPI
bool "ACPI (Advanced Configuration and Power Interface) Support" bool "ACPI (Advanced Configuration and Power Interface) Support"
depends on !X86_VISWS
depends on !IA64_HP_SIM depends on !IA64_HP_SIM
depends on IA64 || X86 depends on IA64 || X86
depends on PCI depends on PCI
......
config LGUEST config LGUEST
tristate "Linux hypervisor example code" tristate "Linux hypervisor example code"
depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !(X86_VISWS || X86_VOYAGER) depends on X86_32 && EXPERIMENTAL && !X86_PAE && FUTEX && !X86_VOYAGER
select HVC_DRIVER select HVC_DRIVER
---help--- ---help---
This is a very simple module which allows you to run This is a very simple module which allows you to run
......
...@@ -21,8 +21,7 @@ ...@@ -21,8 +21,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <asm/visws/sgivw.h>
#include <setup_arch.h>
#define INCLUDE_TIMING_TABLE_DATA #define INCLUDE_TIMING_TABLE_DATA
#define DBE_REG_BASE par->regs #define DBE_REG_BASE par->regs
......
...@@ -107,9 +107,9 @@ ...@@ -107,9 +107,9 @@
#define LAST_VM86_IRQ 15 #define LAST_VM86_IRQ 15
#define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15) #define invalid_vm86_irq(irq) ((irq) < 3 || (irq) > 15)
#if !defined(CONFIG_X86_VISWS) && !defined(CONFIG_X86_VOYAGER) #if !defined(CONFIG_X86_VOYAGER)
# if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) # if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT) || defined(CONFIG_X86_VISWS)
# define NR_IRQS 224 # define NR_IRQS 224
......
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
static inline void smpboot_clear_io_apic_irqs(void) static inline void smpboot_clear_io_apic_irqs(void)
{ {
#ifdef CONFIG_X86_IO_APIC
io_apic_irqs = 0; io_apic_irqs = 0;
#endif
} }
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
...@@ -35,6 +37,7 @@ static inline void smpboot_restore_warm_reset_vector(void) ...@@ -35,6 +37,7 @@ static inline void smpboot_restore_warm_reset_vector(void)
static inline void __init smpboot_setup_io_apic(void) static inline void __init smpboot_setup_io_apic(void)
{ {
#ifdef CONFIG_X86_IO_APIC
/* /*
* Here we can be sure that there is an IO-APIC in the system. Let's * Here we can be sure that there is an IO-APIC in the system. Let's
* go and set it up: * go and set it up:
...@@ -45,9 +48,12 @@ static inline void __init smpboot_setup_io_apic(void) ...@@ -45,9 +48,12 @@ static inline void __init smpboot_setup_io_apic(void)
nr_ioapics = 0; nr_ioapics = 0;
localise_nmi_watchdog(); localise_nmi_watchdog();
} }
#endif
} }
static inline void smpboot_clear_io_apic(void) static inline void smpboot_clear_io_apic(void)
{ {
#ifdef CONFIG_X86_IO_APIC
nr_ioapics = 0; nr_ioapics = 0;
#endif
} }
#ifndef __ASM_MACH_APIC_H #include "../mach-default/mach_apic.h"
#define __ASM_MACH_APIC_H
#include <mach_apicdef.h>
#include <asm/smp.h>
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
#define no_balance_irq (0)
#define esr_disable (0)
#define INT_DELIVERY_MODE dest_LowestPrio
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
#ifdef CONFIG_SMP
#define TARGET_CPUS cpu_online_map
#else
#define TARGET_CPUS cpumask_of_cpu(0)
#endif
#define check_apicid_used(bitmap, apicid) physid_isset(apicid, bitmap)
#define check_apicid_present(bit) physid_isset(bit, phys_cpu_present_map)
static inline int apic_id_registered(void)
{
return physid_isset(GET_APIC_ID(read_apic_id()), phys_cpu_present_map);
}
/*
* Set up the logical destination ID.
*
* Intel recommends to set DFR, LDR and TPR before enabling
* an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
* document number 292116). So here it goes...
*/
static inline void init_apic_ldr(void)
{
unsigned long val;
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
apic_write_around(APIC_LDR, val);
}
static inline void summit_check(char *oem, char *productid)
{
}
static inline void setup_apic_routing(void)
{
}
static inline int apicid_to_node(int logical_apicid)
{
return 0;
}
/* Mapping from cpu number to logical apicid */
static inline int cpu_to_logical_apicid(int cpu)
{
return 1 << cpu;
}
static inline int cpu_present_to_apicid(int mps_cpu)
{
if (mps_cpu < get_physical_broadcast())
return mps_cpu;
else
return BAD_APICID;
}
static inline physid_mask_t apicid_to_cpu_present(int apicid)
{
return physid_mask_of_physid(apicid);
}
#define WAKE_SECONDARY_VIA_INIT
static inline void setup_portio_remap(void)
{
}
static inline void enable_apic_mode(void)
{
}
static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
{
return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
}
static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
{
return cpus_addr(cpumask)[0];
}
static inline u32 phys_pkg_id(u32 cpuid_apic, int index_msb)
{
return cpuid_apic >> index_msb;
}
#endif /* __ASM_MACH_APIC_H */
#ifndef __ASM_MACH_APICDEF_H #include "../mach-default/mach_apicdef.h"
#define __ASM_MACH_APICDEF_H
#define APIC_ID_MASK (0xF<<24)
static inline unsigned get_apic_id(unsigned long x)
{
return (((x)>>24)&0xF);
}
#define GET_APIC_ID(x) get_apic_id(x)
#endif
/* Hook to call BIOS initialisation function */ #include "../mach-default/setup_arch.h"
extern unsigned long sgivwfb_mem_phys;
extern unsigned long sgivwfb_mem_size;
/* no action for visws */
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) #include "../mach-default/smpboot_hooks.h"
{
CMOS_WRITE(0xa, 0xf);
local_flush_tlb();
Dprintk("1.\n");
*((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4;
Dprintk("2.\n");
*((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf;
Dprintk("3.\n");
}
/* for visws do nothing for any of these */
static inline void smpboot_clear_io_apic_irqs(void)
{
}
static inline void smpboot_restore_warm_reset_vector(void)
{
}
static inline void smpboot_setup_io_apic(void)
{
}
static inline void smpboot_clear_io_apic(void)
{
}
...@@ -8,6 +8,25 @@ ...@@ -8,6 +8,25 @@
/* Interrupt control for vSMPowered x86_64 systems */ /* Interrupt control for vSMPowered x86_64 systems */
void vsmp_init(void); void vsmp_init(void);
#ifdef CONFIG_X86_VISWS
extern void visws_early_detect(void);
extern int is_visws_box(void);
#else
static inline void visws_early_detect(void) { }
static inline int is_visws_box(void) { return 0; }
#endif
/*
* Any setup quirks to be performed?
*/
extern int (*arch_time_init_quirk)(void);
extern int (*arch_pre_intr_init_quirk)(void);
extern int (*arch_intr_init_quirk)(void);
extern int (*arch_trap_init_quirk)(void);
extern char * (*arch_memory_setup_quirk)(void);
extern int (*mach_get_smp_config_quirk)(unsigned int early);
extern int (*mach_find_smp_config_quirk)(unsigned int reserve);
#ifndef CONFIG_PARAVIRT #ifndef CONFIG_PARAVIRT
#define paravirt_post_allocator_init() do {} while (0) #define paravirt_post_allocator_init() do {} while (0)
#endif #endif
......
/*
* Frame buffer position and size:
*/
extern unsigned long sgivwfb_mem_phys;
extern unsigned long sgivwfb_mem_size;
...@@ -150,7 +150,7 @@ ...@@ -150,7 +150,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/mach-visws/cobalt.h> #include <asm/visws/cobalt.h>
#include "sound_config.h" #include "sound_config.h"
......
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