[PATCH] Move early chipset quirks out to new file
They did not really belong into io_apic.c. Move them into a new file and clean it up a bit. Also remove outdated ATI quirk that was obsolete, Signed-off-by: Andi Kleen <ak@suse.de>
This commit is contained in:
parent
edd9652296
commit
dfa4698c50
5 changed files with 121 additions and 104 deletions
|
@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
|
||||||
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
|
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
|
||||||
x8664_ksyms.o i387.o syscall.o vsyscall.o \
|
x8664_ksyms.o i387.o syscall.o vsyscall.o \
|
||||||
setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
|
setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
|
||||||
pci-dma.o pci-nommu.o alternative.o
|
pci-dma.o pci-nommu.o alternative.o early-quirks.o
|
||||||
|
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||||
obj-$(CONFIG_X86_MCE) += mce.o
|
obj-$(CONFIG_X86_MCE) += mce.o
|
||||||
|
|
118
arch/x86_64/kernel/early-quirks.c
Normal file
118
arch/x86_64/kernel/early-quirks.c
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/* Various workarounds for chipset bugs.
|
||||||
|
This code runs very early and can't use the regular PCI subsystem
|
||||||
|
The entries are keyed to PCI bridges which usually identify chipsets
|
||||||
|
uniquely.
|
||||||
|
This is only for whole classes of chipsets with specific problems which
|
||||||
|
need early invasive action (e.g. before the timers are initialized).
|
||||||
|
Most PCI device specific workarounds can be done later and should be
|
||||||
|
in standard PCI quirks
|
||||||
|
Mainboard specific bugs should be handled by DMI entries.
|
||||||
|
CPU specific bugs in setup.c */
|
||||||
|
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/pci_ids.h>
|
||||||
|
#include <asm/pci-direct.h>
|
||||||
|
#include <asm/proto.h>
|
||||||
|
#include <asm/dma.h>
|
||||||
|
|
||||||
|
static void via_bugs(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_IOMMU
|
||||||
|
if ((end_pfn > MAX_DMA32_PFN || force_iommu) &&
|
||||||
|
!iommu_aperture_allowed) {
|
||||||
|
printk(KERN_INFO
|
||||||
|
"Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
|
||||||
|
iommu_aperture_disabled = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI
|
||||||
|
|
||||||
|
static int nvidia_hpet_detected __initdata;
|
||||||
|
|
||||||
|
static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
|
||||||
|
{
|
||||||
|
nvidia_hpet_detected = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void nvidia_bugs(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_ACPI
|
||||||
|
/*
|
||||||
|
* All timer overrides on Nvidia are
|
||||||
|
* wrong unless HPET is enabled.
|
||||||
|
*/
|
||||||
|
nvidia_hpet_detected = 0;
|
||||||
|
acpi_table_parse(ACPI_HPET, nvidia_hpet_check);
|
||||||
|
if (nvidia_hpet_detected == 0) {
|
||||||
|
acpi_skip_timer_override = 1;
|
||||||
|
printk(KERN_INFO "Nvidia board "
|
||||||
|
"detected. Ignoring ACPI "
|
||||||
|
"timer override.\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* RED-PEN skip them on mptables too? */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ati_bugs(void)
|
||||||
|
{
|
||||||
|
#if 1 /* for testing */
|
||||||
|
printk("ATI board detected\n");
|
||||||
|
#endif
|
||||||
|
/* No bugs right now */
|
||||||
|
}
|
||||||
|
|
||||||
|
struct chipset {
|
||||||
|
u16 vendor;
|
||||||
|
void (*f)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct chipset early_qrk[] = {
|
||||||
|
{ PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
|
||||||
|
{ PCI_VENDOR_ID_VIA, via_bugs },
|
||||||
|
{ PCI_VENDOR_ID_ATI, ati_bugs },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init early_quirks(void)
|
||||||
|
{
|
||||||
|
int num, slot, func;
|
||||||
|
/* Poor man's PCI discovery */
|
||||||
|
for (num = 0; num < 32; num++) {
|
||||||
|
for (slot = 0; slot < 32; slot++) {
|
||||||
|
for (func = 0; func < 8; func++) {
|
||||||
|
u32 class;
|
||||||
|
u32 vendor;
|
||||||
|
u8 type;
|
||||||
|
int i;
|
||||||
|
class = read_pci_config(num,slot,func,
|
||||||
|
PCI_CLASS_REVISION);
|
||||||
|
if (class == 0xffffffff)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
vendor = read_pci_config(num, slot, func,
|
||||||
|
PCI_VENDOR_ID);
|
||||||
|
vendor &= 0xffff;
|
||||||
|
|
||||||
|
for (i = 0; early_qrk[i].f; i++)
|
||||||
|
if (early_qrk[i].vendor == vendor) {
|
||||||
|
early_qrk[i].f();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = read_pci_config_byte(num, slot, func,
|
||||||
|
PCI_HEADER_TYPE);
|
||||||
|
if (!(type & 0x80))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -280,107 +280,6 @@ static int __init setup_enable_8254_timer(char *s)
|
||||||
__setup("disable_8254_timer", setup_disable_8254_timer);
|
__setup("disable_8254_timer", setup_disable_8254_timer);
|
||||||
__setup("enable_8254_timer", setup_enable_8254_timer);
|
__setup("enable_8254_timer", setup_enable_8254_timer);
|
||||||
|
|
||||||
#include <asm/pci-direct.h>
|
|
||||||
#include <linux/pci_ids.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
|
||||||
|
|
||||||
static int nvidia_hpet_detected __initdata;
|
|
||||||
|
|
||||||
static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
|
|
||||||
{
|
|
||||||
nvidia_hpet_detected = 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC
|
|
||||||
off. Check for an Nvidia or VIA PCI bridge and turn it off.
|
|
||||||
Use pci direct infrastructure because this runs before the PCI subsystem.
|
|
||||||
|
|
||||||
Can be overwritten with "apic"
|
|
||||||
|
|
||||||
And another hack to disable the IOMMU on VIA chipsets.
|
|
||||||
|
|
||||||
... and others. Really should move this somewhere else.
|
|
||||||
|
|
||||||
Kludge-O-Rama. */
|
|
||||||
void __init check_ioapic(void)
|
|
||||||
{
|
|
||||||
int num,slot,func;
|
|
||||||
/* Poor man's PCI discovery */
|
|
||||||
for (num = 0; num < 32; num++) {
|
|
||||||
for (slot = 0; slot < 32; slot++) {
|
|
||||||
for (func = 0; func < 8; func++) {
|
|
||||||
u32 class;
|
|
||||||
u32 vendor;
|
|
||||||
u8 type;
|
|
||||||
class = read_pci_config(num,slot,func,
|
|
||||||
PCI_CLASS_REVISION);
|
|
||||||
if (class == 0xffffffff)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vendor = read_pci_config(num, slot, func,
|
|
||||||
PCI_VENDOR_ID);
|
|
||||||
vendor &= 0xffff;
|
|
||||||
switch (vendor) {
|
|
||||||
case PCI_VENDOR_ID_VIA:
|
|
||||||
#ifdef CONFIG_IOMMU
|
|
||||||
if ((end_pfn > MAX_DMA32_PFN ||
|
|
||||||
force_iommu) &&
|
|
||||||
!iommu_aperture_allowed) {
|
|
||||||
printk(KERN_INFO
|
|
||||||
"Looks like a VIA chipset. Disabling IOMMU. Override with \"iommu=allowed\"\n");
|
|
||||||
iommu_aperture_disabled = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
case PCI_VENDOR_ID_NVIDIA:
|
|
||||||
#ifdef CONFIG_ACPI
|
|
||||||
/*
|
|
||||||
* All timer overrides on Nvidia are
|
|
||||||
* wrong unless HPET is enabled.
|
|
||||||
*/
|
|
||||||
nvidia_hpet_detected = 0;
|
|
||||||
acpi_table_parse(ACPI_HPET,
|
|
||||||
nvidia_hpet_check);
|
|
||||||
if (nvidia_hpet_detected == 0) {
|
|
||||||
acpi_skip_timer_override = 1;
|
|
||||||
printk(KERN_INFO "Nvidia board "
|
|
||||||
"detected. Ignoring ACPI "
|
|
||||||
"timer override.\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* RED-PEN skip them on mptables too? */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* This should be actually default, but
|
|
||||||
for 2.6.16 let's do it for ATI only where
|
|
||||||
it's really needed. */
|
|
||||||
case PCI_VENDOR_ID_ATI:
|
|
||||||
if (timer_over_8254 == 1) {
|
|
||||||
timer_over_8254 = 0;
|
|
||||||
printk(KERN_INFO
|
|
||||||
"ATI board detected. Disabling timer routing over 8254.\n");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* No multi-function device? */
|
|
||||||
type = read_pci_config_byte(num,slot,func,
|
|
||||||
PCI_HEADER_TYPE);
|
|
||||||
if (!(type & 0x80))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the IRQ entry number of a certain pin.
|
* Find the IRQ entry number of a certain pin.
|
||||||
|
|
|
@ -653,7 +653,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
|
|
||||||
paging_init();
|
paging_init();
|
||||||
|
|
||||||
check_ioapic();
|
early_quirks();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set this early, so we dont allocate cpu0
|
* set this early, so we dont allocate cpu0
|
||||||
|
|
|
@ -92,7 +92,7 @@ extern void syscall32_cpu_init(void);
|
||||||
|
|
||||||
extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end);
|
extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end);
|
||||||
|
|
||||||
extern void check_ioapic(void);
|
extern void early_quirks(void);
|
||||||
extern void check_efer(void);
|
extern void check_efer(void);
|
||||||
|
|
||||||
extern int unhandled_signal(struct task_struct *tsk, int sig);
|
extern int unhandled_signal(struct task_struct *tsk, int sig);
|
||||||
|
|
Loading…
Add table
Reference in a new issue