diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 9836a079cfd9c8621cdb1d8844b796947485987b..269d367d2ace623e57c5f7fd426cbaf1d8a2fe08 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -1297,6 +1297,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 *who = "BIOS-e820"; @@ -1337,6 +1342,12 @@ char *__init default_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(); } diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 8b6b1e05c306ff16121bcdd4b06222718b47522c..3b25e49380c6eed8ff660d409afb2deda8c428cd 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -725,13 +725,23 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) 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. */ -static void __init __get_smp_config(unsigned early) +static void __init __get_smp_config(unsigned int early) { 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) return; /* @@ -889,10 +899,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length, 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; + if (mach_find_smp_config_quirk) { + if (mach_find_smp_config_quirk(reserve)) + return; + } /* * FIXME: Linux assumes you have 640K of base ram.. * this continues the error... diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index a7c3471ea17c1e43899bd380c3380daa5e4b2d3d..cb3db406247cdc261e3a405409ebc41ea9f069b1 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -596,6 +596,7 @@ void __init setup_arch(char **cmdline_p) { #ifdef CONFIG_X86_32 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); + visws_early_detect(); pre_setup_arch_hook(); early_cpu_init(); #else diff --git a/include/asm-x86/setup.h b/include/asm-x86/setup.h index 1d121c632d9e7ad57a61144161886508d5ccb664..1ad7eae0d9be1b6546aea4c67e0242b4f767cf86 100644 --- a/include/asm-x86/setup.h +++ b/include/asm-x86/setup.h @@ -8,6 +8,23 @@ /* Interrupt control for vSMPowered x86_64 systems */ void vsmp_init(void); +#ifdef CONFIG_X86_VISWS +extern void visws_early_detect(void); +#else +static inline void visws_early_detect(void) { } +#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 #define paravirt_post_allocator_init() do {} while (0) #endif