Add early quirks support.
In preparation of enabling the generic architecture to boot on a VISWS.
This will allow us to remove the VISWS subarch and all its complications.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
        }
 }
 
+/*
+ * 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";
 
 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();
 }
 
 
 
 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;
        /*
        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...
 
 {
 #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
 
 /* 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