Commit 3c9cb6de authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar

x86: introduce x86_quirks

introduce x86_quirks array of boot-time quirk methods.

No change in functionality intended.
Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 5f1f2b3d
...@@ -1299,11 +1299,6 @@ void __init e820_reserve_resources(void) ...@@ -1299,11 +1299,6 @@ 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";
...@@ -1344,8 +1339,8 @@ char *__init default_machine_specific_memory_setup(void) ...@@ -1344,8 +1339,8 @@ 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) { if (x86_quirks->arch_memory_setup) {
char *who = arch_memory_setup_quirk(); char *who = x86_quirks->arch_memory_setup();
if (who) if (who)
return who; return who;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <asm/bios_ebda.h> #include <asm/bios_ebda.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/trampoline.h> #include <asm/trampoline.h>
#include <asm/setup.h>
#include <mach_apic.h> #include <mach_apic.h>
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
...@@ -725,12 +726,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) ...@@ -725,12 +726,6 @@ 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.
*/ */
...@@ -738,8 +733,8 @@ static void __init __get_smp_config(unsigned int early) ...@@ -738,8 +733,8 @@ 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 (x86_quirks->mach_get_smp_config) {
if (mach_get_smp_config_quirk(early)) if (x86_quirks->mach_get_smp_config(early))
return; return;
} }
if (acpi_lapic && early) if (acpi_lapic && early)
...@@ -899,14 +894,12 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, ...@@ -899,14 +894,12 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
return 0; return 0;
} }
int (*mach_find_smp_config_quirk)(unsigned int reserve);
static void __init __find_smp_config(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 (x86_quirks->mach_find_smp_config) {
if (mach_find_smp_config_quirk(reserve)) if (x86_quirks->mach_find_smp_config(reserve))
return; return;
} }
/* /*
......
...@@ -574,6 +574,10 @@ static int __init setup_elfcorehdr(char *arg) ...@@ -574,6 +574,10 @@ static int __init setup_elfcorehdr(char *arg)
early_param("elfcorehdr", setup_elfcorehdr); early_param("elfcorehdr", setup_elfcorehdr);
#endif #endif
static struct x86_quirks default_x86_quirks __initdata;
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
/* /*
* Determine if we were loaded by an EFI loader. If so, then we have also been * Determine if we were loaded by an EFI loader. If so, then we have also been
* passed the efi memmap, systab, etc., so we should use these data structures * passed the efi memmap, systab, etc., so we should use these data structures
......
...@@ -73,7 +73,7 @@ int is_visws_box(void) ...@@ -73,7 +73,7 @@ int is_visws_box(void)
return visws_board_type >= 0; return visws_board_type >= 0;
} }
static int __init visws_time_init_quirk(void) static int __init visws_time_init(void)
{ {
printk(KERN_INFO "Starting Cobalt Timer system clock\n"); printk(KERN_INFO "Starting Cobalt Timer system clock\n");
...@@ -93,7 +93,7 @@ static int __init visws_time_init_quirk(void) ...@@ -93,7 +93,7 @@ static int __init visws_time_init_quirk(void)
return 0; return 0;
} }
static int __init visws_pre_intr_init_quirk(void) static int __init visws_pre_intr_init(void)
{ {
init_VISWS_APIC_irqs(); init_VISWS_APIC_irqs();
...@@ -114,7 +114,7 @@ EXPORT_SYMBOL(sgivwfb_mem_size); ...@@ -114,7 +114,7 @@ EXPORT_SYMBOL(sgivwfb_mem_size);
long long mem_size __initdata = 0; long long mem_size __initdata = 0;
static char * __init visws_memory_setup_quirk(void) static char * __init visws_memory_setup(void)
{ {
long long gfx_mem_size = 8 * MB; long long gfx_mem_size = 8 * MB;
...@@ -176,7 +176,7 @@ static void visws_machine_power_off(void) ...@@ -176,7 +176,7 @@ static void visws_machine_power_off(void)
outl(PIIX_SPECIAL_STOP, 0xCFC); outl(PIIX_SPECIAL_STOP, 0xCFC);
} }
static int __init visws_get_smp_config_quirk(unsigned int early) static int __init visws_get_smp_config(unsigned int early)
{ {
/* /*
* Prevent MP-table parsing by the generic code: * Prevent MP-table parsing by the generic code:
...@@ -192,7 +192,7 @@ extern unsigned int __cpuinitdata maxcpus; ...@@ -192,7 +192,7 @@ extern unsigned int __cpuinitdata maxcpus;
* No problem for Linux. * No problem for Linux.
*/ */
static void __init MP_processor_info (struct mpc_config_processor *m) static void __init MP_processor_info(struct mpc_config_processor *m)
{ {
int ver, logical_apicid; int ver, logical_apicid;
physid_mask_t apic_cpus; physid_mask_t apic_cpus;
...@@ -232,7 +232,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m) ...@@ -232,7 +232,7 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
apic_version[m->mpc_apicid] = ver; apic_version[m->mpc_apicid] = ver;
} }
int __init visws_find_smp_config_quirk(unsigned int reserve) static int __init visws_find_smp_config(unsigned int reserve)
{ {
struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS); struct mpc_config_processor *mp = phys_to_virt(CO_CPU_TAB_PHYS);
unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS)); unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
...@@ -258,7 +258,17 @@ int __init visws_find_smp_config_quirk(unsigned int reserve) ...@@ -258,7 +258,17 @@ int __init visws_find_smp_config_quirk(unsigned int reserve)
return 1; return 1;
} }
extern int visws_trap_init_quirk(void); static int visws_trap_init(void);
static struct x86_quirks visws_x86_quirks __initdata = {
.arch_time_init = visws_time_init,
.arch_pre_intr_init = visws_pre_intr_init,
.arch_memory_setup = visws_memory_setup,
.arch_intr_init = NULL,
.arch_trap_init = visws_trap_init,
.mach_get_smp_config = visws_get_smp_config,
.mach_find_smp_config = visws_find_smp_config,
};
void __init visws_early_detect(void) void __init visws_early_detect(void)
{ {
...@@ -272,16 +282,10 @@ void __init visws_early_detect(void) ...@@ -272,16 +282,10 @@ void __init visws_early_detect(void)
/* /*
* Install special quirks for timer, interrupt and memory setup: * Install special quirks for timer, interrupt and memory setup:
*/
arch_time_init_quirk = visws_time_init_quirk;
arch_pre_intr_init_quirk = visws_pre_intr_init_quirk;
arch_memory_setup_quirk = visws_memory_setup_quirk;
/*
* Fall back to generic behavior for traps: * Fall back to generic behavior for traps:
* Override generic MP-table parsing:
*/ */
arch_intr_init_quirk = NULL; x86_quirks = &visws_x86_quirks;
arch_trap_init_quirk = visws_trap_init_quirk;
/* /*
* Install reboot quirks: * Install reboot quirks:
...@@ -294,12 +298,6 @@ void __init visws_early_detect(void) ...@@ -294,12 +298,6 @@ void __init visws_early_detect(void)
*/ */
no_broadcast = 0; no_broadcast = 0;
/*
* Override generic MP-table parsing:
*/
mach_get_smp_config_quirk = visws_get_smp_config_quirk;
mach_find_smp_config_quirk = visws_find_smp_config_quirk;
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
/* /*
* Turn off IO-APIC detection and initialization: * Turn off IO-APIC detection and initialization:
...@@ -426,7 +424,7 @@ static __init void cobalt_init(void) ...@@ -426,7 +424,7 @@ static __init void cobalt_init(void)
co_apic_read(CO_APIC_ID)); co_apic_read(CO_APIC_ID));
} }
int __init visws_trap_init_quirk(void) static int __init visws_trap_init(void)
{ {
lithium_init(); lithium_init();
cobalt_init(); cobalt_init();
......
...@@ -10,14 +10,6 @@ ...@@ -10,14 +10,6 @@
#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
...@@ -37,8 +29,8 @@ int no_broadcast=DEFAULT_SEND_IPI; ...@@ -37,8 +29,8 @@ 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 (x86_quirks->arch_pre_intr_init) {
if (arch_pre_intr_init_quirk()) if (x86_quirks->arch_pre_intr_init())
return; return;
} }
init_ISA_irqs(); init_ISA_irqs();
...@@ -64,8 +56,8 @@ static struct irqaction irq2 = { ...@@ -64,8 +56,8 @@ static struct irqaction irq2 = {
**/ **/
void __init intr_init_hook(void) void __init intr_init_hook(void)
{ {
if (arch_intr_init_quirk) { if (x86_quirks->arch_intr_init) {
if (arch_intr_init_quirk()) if (x86_quirks->arch_intr_init())
return; return;
} }
#ifdef CONFIG_X86_LOCAL_APIC #ifdef CONFIG_X86_LOCAL_APIC
...@@ -97,8 +89,8 @@ void __init pre_setup_arch_hook(void) ...@@ -97,8 +89,8 @@ 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 (x86_quirks->arch_trap_init) {
if (arch_trap_init_quirk()) if (x86_quirks->arch_trap_init())
return; return;
} }
} }
...@@ -119,13 +111,13 @@ static struct irqaction irq0 = { ...@@ -119,13 +111,13 @@ static struct irqaction irq0 = {
**/ **/
void __init time_init_hook(void) void __init time_init_hook(void)
{ {
if (arch_time_init_quirk) { if (x86_quirks->arch_time_init) {
/* /*
* A nonzero return code does not mean failure, it means * A nonzero return code does not mean failure, it means
* that the architecture quirk does not want any * that the architecture quirk does not want any
* generic (timer) setup to be performed after this: * generic (timer) setup to be performed after this:
*/ */
if (arch_time_init_quirk()) if (x86_quirks->arch_time_init())
return; return;
} }
......
...@@ -19,13 +19,17 @@ static inline int is_visws_box(void) { return 0; } ...@@ -19,13 +19,17 @@ static inline int is_visws_box(void) { return 0; }
/* /*
* Any setup quirks to be performed? * Any setup quirks to be performed?
*/ */
extern int (*arch_time_init_quirk)(void); struct x86_quirks {
extern int (*arch_pre_intr_init_quirk)(void); int (*arch_time_init)(void);
extern int (*arch_intr_init_quirk)(void); int (*arch_pre_intr_init)(void);
extern int (*arch_trap_init_quirk)(void); int (*arch_intr_init)(void);
extern char * (*arch_memory_setup_quirk)(void); int (*arch_trap_init)(void);
extern int (*mach_get_smp_config_quirk)(unsigned int early); char * (*arch_memory_setup)(void);
extern int (*mach_find_smp_config_quirk)(unsigned int reserve); int (*mach_get_smp_config)(unsigned int early);
int (*mach_find_smp_config)(unsigned int reserve);
};
extern struct x86_quirks *x86_quirks;
#ifndef CONFIG_PARAVIRT #ifndef CONFIG_PARAVIRT
#define paravirt_post_allocator_init() do {} while (0) #define paravirt_post_allocator_init() do {} while (0)
......
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