#include <asm/idle.h>
 #include <asm/proto.h>
 #include <asm/timex.h>
+#include <asm/apic.h>
 
 int apic_verbosity;
 int apic_runs_main_timer;
 
 static int __init apic_set_verbosity(char *str)
 {
+       if (str == NULL)  {
+               skip_ioapic_setup = 0;
+               ioapic_force = 1;
+               return 0;
+       }
        if (strcmp("debug", str) == 0)
                apic_verbosity = APIC_DEBUG;
        else if (strcmp("verbose", str) == 0)
                apic_verbosity = APIC_VERBOSE;
-       else
+       else {
                printk(KERN_WARNING "APIC Verbosity level %s not recognised"
-                               " use apic=verbose or apic=debug", str);
+                               " use apic=verbose or apic=debug\n", str);
+               return -EINVAL;
+       }
 
-       return 1;
+       return 0;
 }
-
-__setup("apic=", apic_set_verbosity);
+early_param("apic", apic_set_verbosity);
 
 /*
  * Detect and enable local APICs on non-SMP boards.
 static __init int setup_disableapic(char *str) 
 { 
        disable_apic = 1;
-       return 1;
-} 
+       clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+       return 0;
+}
+early_param("disableapic", setup_disableapic);
 
+/* same as disableapic, for compatibility */
 static __init int setup_nolapic(char *str) 
 { 
-       disable_apic = 1;
-       return 1;
+       return setup_disableapic(str);
 } 
+early_param("nolapic", setup_nolapic);
 
 static __init int setup_noapictimer(char *str) 
 { 
 }
 __setup("apicpmtimer", setup_apicpmtimer);
 
-/* dummy parsing: see setup.c */
-
-__setup("disableapic", setup_disableapic); 
-__setup("nolapic", setup_nolapic);  /* same as disableapic, for compatibility */
-
 __setup("noapictimer", setup_noapictimer); 
 
-/* no "lapic" flag - we only use the lapic when the BIOS tells us so. */
 
        e820_print_map(who);
 }
 
-void __init parse_memopt(char *p, char **from) 
-{ 
-       end_user_pfn = memparse(p, from);
+static int __init parse_memopt(char *p)
+{
+       if (!p)
+               return -EINVAL;
+       end_user_pfn = memparse(p, &p);
        end_user_pfn >>= PAGE_SHIFT;    
+       return 0;
 } 
+early_param("mem", parse_memopt);
+
+static int userdef __initdata;
 
-void __init parse_memmapopt(char *p, char **from)
+static int __init parse_memmap_opt(char *p)
 {
+       char *oldp;
        unsigned long long start_at, mem_size;
 
-       mem_size = memparse(p, from);
-       p = *from;
+       if (!strcmp(p, "exactmap")) {
+#ifdef CONFIG_CRASH_DUMP
+               /* If we are doing a crash dump, we
+                * still need to know the real mem
+                * size before original memory map is
+                * reset.
+                */
+               saved_max_pfn = e820_end_of_ram();
+#endif
+               end_pfn_map = 0;
+               e820.nr_map = 0;
+               userdef = 1;
+               return 0;
+       }
+
+       oldp = p;
+       mem_size = memparse(p, &p);
+       if (p == oldp)
+               return -EINVAL;
        if (*p == '@') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_RAM);
        } else if (*p == '#') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_ACPI);
        } else if (*p == '$') {
-               start_at = memparse(p+1, from);
+               start_at = memparse(p+1, &p);
                add_memory_region(start_at, mem_size, E820_RESERVED);
        } else {
                end_user_pfn = (mem_size >> PAGE_SHIFT);
        }
-       p = *from;
+       return *p == '\0' ? 0 : -EINVAL;
+}
+early_param("memmap", parse_memmap_opt);
+
+void finish_e820_parsing(void)
+{
+       if (userdef) {
+               printk(KERN_INFO "user-defined physical RAM map:\n");
+               e820_print_map("user");
+       }
 }
 
 unsigned long pci_mem_start = 0xaeedbabe;
 
 
 static int __initdata keep_early;
 
-int __init setup_early_printk(char *opt)
+static int __init setup_early_printk(char *buf)
 {
-       char *space;
-       char buf[256];
+       if (!buf)
+               return 0;
 
        if (early_console_initialized)
-               return 1;
-
-       strlcpy(buf,opt,sizeof(buf));
-       space = strchr(buf, ' ');
-       if (space)
-               *space = 0;
+               return 0;
+       early_console_initialized = 1;
 
-       if (strstr(buf,"keep"))
+       if (!strcmp(buf,"keep"))
                keep_early = 1;
 
        if (!strncmp(buf, "serial", 6)) {
                early_console = &simnow_console;
                keep_early = 1;
        }
-       early_console_initialized = 1;
        register_console(early_console);
        return 0;
 }
 
+early_param("earlyprintk", setup_early_printk);
+
 void __init disable_early_printk(void)
 {
        if (!early_console_initialized || !early_console)
        }
 }
 
-__setup("earlyprintk=", setup_early_printk);
 
 
 void __init x86_64_start_kernel(char * real_mode_data)
 {
-       char *s;
        int i;
 
        for (i = 0; i < 256; i++)
 #ifdef CONFIG_SMP
        cpu_set(0, cpu_online_map);
 #endif
-       s = strstr(saved_command_line, "earlyprintk=");
-       if (s != NULL)
-               setup_early_printk(strchr(s, '=') + 1);
-#ifdef CONFIG_NUMA
-       s = strstr(saved_command_line, "numa=");
-       if (s != NULL)
-               numa_setup(s+5);
-#endif
-       if (strstr(saved_command_line, "disableapic"))
-               disable_apic = 1;
-       /* You need early console to see that */
-       if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
-               panic("Kernel too big for kernel mapping\n");
-
        start_kernel();
 }
 
 
 static int no_timer_check;
 
-int disable_timer_pin_1 __initdata;
+static int disable_timer_pin_1 __initdata;
 
 int timer_over_8254 __initdata = 0;
 
 static int __init disable_ioapic_setup(char *str)
 {
        skip_ioapic_setup = 1;
-       return 1;
+       return 0;
 }
+early_param("noapic", disable_ioapic_setup);
 
-static int __init enable_ioapic_setup(char *str)
+/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
+static int __init disable_timer_pin_setup(char *arg)
 {
-       ioapic_force = 1;
-       skip_ioapic_setup = 0;
+       disable_timer_pin_1 = 1;
        return 1;
 }
-
-__setup("noapic", disable_ioapic_setup);
-__setup("apic", enable_ioapic_setup);
+__setup("disable_timer_pin_1", disable_timer_pin_setup);
 
 static int __init setup_disable_8254_timer(char *s)
 {
 
        rnk = (relocate_new_kernel_t) control_code_buffer;
        (*rnk)(page_list, control_code_buffer, image->start, start_pgtable);
 }
+
+/* crashkernel=size@addr specifies the location to reserve for
+ * a crash kernel.  By reserving this memory we guarantee
+ * that linux never set's it up as a DMA target.
+ * Useful for holding code to do something appropriate
+ * after a kernel panic.
+ */
+static int __init setup_crashkernel(char *arg)
+{
+       unsigned long size, base;
+       char *p;
+       if (!arg)
+               return -EINVAL;
+       size = memparse(arg, &p);
+       if (arg == p)
+               return -EINVAL;
+       if (*p == '@') {
+               base = memparse(p+1, &p);
+               /* FIXME: Do I want a sanity check to validate the
+                * memory range?  Yes you do, but it's too early for
+                * e820 -AK */
+               crashk_res.start = base;
+               crashk_res.end   = base + size - 1;
+       }
+       return 0;
+}
+early_param("crashkernel", setup_crashkernel);
+
 
 {
     iommu_merge = 1;
 
+       if (!p)
+               return -EINVAL;
+
     while (*p) {
            if (!strncmp(p,"off",3))
                    no_iommu = 1;
            if (*p == ',')
                    ++p;
     }
-    return 1;
+    return 0;
 }
-__setup("iommu=", iommu_setup);
+early_param("iommu", iommu_setup);
 
 void __init pci_iommu_alloc(void)
 {
 
 
 int acpi_disabled;
 EXPORT_SYMBOL(acpi_disabled);
-#ifdef CONFIG_ACPI
-extern int __initdata acpi_ht;
-extern acpi_interrupt_flags    acpi_sci_flags;
-int __initdata acpi_force = 0;
-#endif
 
 int acpi_numa __initdata;
 
        }
 }
 
-/* Check for full argument with no trailing characters */
-static int fullarg(char *p, char *arg)
+#ifdef CONFIG_PROC_VMCORE
+/* elfcorehdr= specifies the location of elf core header
+ * stored by the crashed kernel. This option will be passed
+ * by kexec loader to the capture kernel.
+ */
+static int __init setup_elfcorehdr(char *arg)
 {
-       int l = strlen(arg);
-       return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l]));
+       char *end;
+       if (!arg)
+               return -EINVAL;
+       elfcorehdr_addr = memparse(arg, &end);
+       return end > arg ? 0 : -EINVAL;
 }
-
-static __init void parse_cmdline_early (char ** cmdline_p)
-{
-       char c = ' ', *to = command_line, *from = COMMAND_LINE;
-       int len = 0;
-       int userdef = 0;
-
-       for (;;) {
-               if (c != ' ') 
-                       goto next_char; 
-
-#ifdef  CONFIG_SMP
-               /*
-                * If the BIOS enumerates physical processors before logical,
-                * maxcpus=N at enumeration-time can be used to disable HT.
-                */
-               else if (!memcmp(from, "maxcpus=", 8)) {
-                       extern unsigned int maxcpus;
-
-                       maxcpus = simple_strtoul(from + 8, NULL, 0);
-               }
-#endif
-#ifdef CONFIG_ACPI
-               /* "acpi=off" disables both ACPI table parsing and interpreter init */
-               if (fullarg(from,"acpi=off"))
-                       disable_acpi();
-
-               if (fullarg(from, "acpi=force")) { 
-                       /* add later when we do DMI horrors: */
-                       acpi_force = 1;
-                       acpi_disabled = 0;
-               }
-
-               /* acpi=ht just means: do ACPI MADT parsing 
-                  at bootup, but don't enable the full ACPI interpreter */
-               if (fullarg(from, "acpi=ht")) { 
-                       if (!acpi_force)
-                               disable_acpi();
-                       acpi_ht = 1; 
-               }
-                else if (fullarg(from, "pci=noacpi")) 
-                       acpi_disable_pci();
-               else if (fullarg(from, "acpi=noirq"))
-                       acpi_noirq_set();
-
-               else if (fullarg(from, "acpi_sci=edge"))
-                       acpi_sci_flags.trigger =  1;
-               else if (fullarg(from, "acpi_sci=level"))
-                       acpi_sci_flags.trigger = 3;
-               else if (fullarg(from, "acpi_sci=high"))
-                       acpi_sci_flags.polarity = 1;
-               else if (fullarg(from, "acpi_sci=low"))
-                       acpi_sci_flags.polarity = 3;
-
-               /* acpi=strict disables out-of-spec workarounds */
-               else if (fullarg(from, "acpi=strict")) {
-                       acpi_strict = 1;
-               }
-               else if (fullarg(from, "acpi_skip_timer_override"))
-                       acpi_skip_timer_override = 1;
+early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-               if (fullarg(from, "disable_timer_pin_1"))
-                       disable_timer_pin_1 = 1;
-               if (fullarg(from, "enable_timer_pin_1"))
-                       disable_timer_pin_1 = -1;
-
-               if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) {
-                       clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
-                       disable_apic = 1;
-               }
-
-               if (fullarg(from, "noapic"))
-                       skip_ioapic_setup = 1;
-
-               if (fullarg(from,"apic")) {
-                       skip_ioapic_setup = 0;
-                       ioapic_force = 1;
-               }
-                       
-               if (!memcmp(from, "mem=", 4))
-                       parse_memopt(from+4, &from); 
-
-               if (!memcmp(from, "memmap=", 7)) {
-                       /* exactmap option is for used defined memory */
-                       if (!memcmp(from+7, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-                               /* If we are doing a crash dump, we
-                                * still need to know the real mem
-                                * size before original memory map is
-                                * reset.
-                                */
-                               saved_max_pfn = e820_end_of_ram();
-#endif
-                               from += 8+7;
-                               end_pfn_map = 0;
-                               e820.nr_map = 0;
-                               userdef = 1;
-                       }
-                       else {
-                               parse_memmapopt(from+7, &from);
-                               userdef = 1;
-                       }
-               }
-
-#ifdef CONFIG_NUMA
-               if (!memcmp(from, "numa=", 5))
-                       numa_setup(from+5); 
-#endif
-
-               if (!memcmp(from,"iommu=",6)) { 
-                       iommu_setup(from+6); 
-               }
-
-               if (fullarg(from,"oops=panic"))
-                       panic_on_oops = 1;
-
-               if (!memcmp(from, "noexec=", 7))
-                       nonx_setup(from + 7);
-
-#ifdef CONFIG_KEXEC
-               /* crashkernel=size@addr specifies the location to reserve for
-                * a crash kernel.  By reserving this memory we guarantee
-                * that linux never set's it up as a DMA target.
-                * Useful for holding code to do something appropriate
-                * after a kernel panic.
-                */
-               else if (!memcmp(from, "crashkernel=", 12)) {
-                       unsigned long size, base;
-                       size = memparse(from+12, &from);
-                       if (*from == '@') {
-                               base = memparse(from+1, &from);
-                               /* FIXME: Do I want a sanity check
-                                * to validate the memory range?
-                                */
-                               crashk_res.start = base;
-                               crashk_res.end   = base + size - 1;
-                       }
-               }
-#endif
-
-#ifdef CONFIG_PROC_VMCORE
-               /* elfcorehdr= specifies the location of elf core header
-                * stored by the crashed kernel. This option will be passed
-                * by kexec loader to the capture kernel.
-                */
-               else if(!memcmp(from, "elfcorehdr=", 11))
-                       elfcorehdr_addr = memparse(from+11, &from);
-#endif
-
-#ifdef CONFIG_HOTPLUG_CPU
-               else if (!memcmp(from, "additional_cpus=", 16))
-                       setup_additional_cpus(from+16);
-#endif
-
-       next_char:
-               c = *(from++);
-               if (!c)
-                       break;
-               if (COMMAND_LINE_SIZE <= ++len)
-                       break;
-               *(to++) = c;
-       }
-       if (userdef) {
-               printk(KERN_INFO "user-defined physical RAM map:\n");
-               e820_print_map("user");
-       }
-       *to = '\0';
-       *cmdline_p = command_line;
-}
-
 #ifndef CONFIG_NUMA
 static void __init
 contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
 
        early_identify_cpu(&boot_cpu_data);
 
-       parse_cmdline_early(cmdline_p);
+       strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
+       *cmdline_p = command_line;
+
+       parse_early_param();
+
+       finish_e820_parsing();
 
        /*
         * partially used pages are not usable - thus
 
 on     Enable(default)
 off    Disable
 */ 
-int __init nonx_setup(char *str)
+static int __init nonx_setup(char *str)
 {
+       if (!str)
+               return -EINVAL;
        if (!strncmp(str, "on", 2)) {
                 __supported_pte_mask |= _PAGE_NX; 
                do_not_nx = 0; 
                do_not_nx = 1;
                __supported_pte_mask &= ~_PAGE_NX;
         }
-       return 1;
+       return 0;
 } 
-__setup("noexec=", nonx_setup);        /* parsed early actually */
+early_param("noexec", nonx_setup);
 
 int force_personality32 = 0; 
 
 
        printk(KERN_ERR "CPU %u didn't die...\n", cpu);
 }
 
-__init int setup_additional_cpus(char *s)
+static __init int setup_additional_cpus(char *s)
 {
-       return get_option(&s, &additional_cpus);
+       return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL;
 }
-__setup("additional_cpus=", setup_additional_cpus);
+early_param("additional_cpus", setup_additional_cpus);
 
 #else /* ... !CONFIG_HOTPLUG_CPU */
 
 
 }
 
 
-/* Actual parsing is done early in setup.c. */
-static int __init oops_dummy(char *s)
+static int __init oops_setup(char *s)
 { 
-       panic_on_oops = 1;
-       return 1;
+       if (!s)
+               return -EINVAL;
+       if (!strcmp(s, "panic"))
+               panic_on_oops = 1;
+       return 0;
 } 
-__setup("oops=", oops_dummy); 
+early_param("oops", oops_setup);
 
 static int __init kstack_setup(char *s)
 {
+       if (!s)
+               return -EINVAL;
        kstack_depth_to_print = simple_strtoul(s,NULL,0);
-       return 1;
+       return 0;
 }
-__setup("kstack=", kstack_setup);
+early_param("kstack", kstack_setup);
 
 #ifdef CONFIG_STACK_UNWIND
 static int __init call_trace_setup(char *s)
 {
+       if (!s)
+               return -EINVAL;
        if (strcmp(s, "old") == 0)
                call_trace = -1;
        else if (strcmp(s, "both") == 0)
                call_trace = 1;
        else if (strcmp(s, "new") == 0)
                call_trace = 2;
-       return 1;
+       return 0;
 }
-__setup("call_trace=", call_trace_setup);
+early_param("call_trace", call_trace_setup);
 #endif
 
        }
 } 
 
-/* [numa=off] */
-__init int numa_setup(char *opt) 
+static __init int numa_setup(char *opt)
 { 
+       if (!opt)
+               return -EINVAL;
        if (!strncmp(opt,"off",3))
                numa_off = 1;
 #ifdef CONFIG_NUMA_EMU
        if (!strncmp(opt,"hotadd=", 7))
                hotadd_percent = simple_strtoul(opt+7, NULL, 10);
 #endif
-       return 1;
+       return 0;
 } 
 
+early_param("numa", numa_setup);
+
 /*
  * Setup early cpu_to_node.
  *
 
 
 extern int apic_verbosity;
 extern int apic_runs_main_timer;
+extern int ioapic_force;
 
 /*
  * Define the default level of output to be very little
 #define K8_APIC_EXT_INT_MSG_EXT 0x7
 #define K8_APIC_EXT_LVT_ENTRY_THRESHOLD    0
 
-extern int disable_timer_pin_1;
-
-
 void smp_send_timer_broadcast_ipi(void);
 void switch_APIC_timer_to_ipi(void *cpumask);
 void switch_ipi_to_APIC_timer(void *cpumask);
 
 extern unsigned long e820_hole_size(unsigned long start_pfn,
                                    unsigned long end_pfn);
 
-extern void __init parse_memopt(char *p, char **end);
-extern void __init parse_memmapopt(char *p, char **end);
+extern void finish_e820_parsing(void);
 
 extern struct e820map e820;
 
 
 
 #define swapper_pg_dir init_level4_pgt
 
-extern int nonx_setup(char *str);
 extern void paging_init(void);
 extern void clear_kernel_mapping(unsigned long addr, unsigned long size);
 
 
 extern unsigned long vxtime_hz;
 extern void time_init_gtod(void);
 
-extern int numa_setup(char *opt);
-
-extern int setup_early_printk(char *); 
 extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2)));
 
 extern void early_identify_cpu(struct cpuinfo_x86 *c);
 extern unsigned long table_start, table_end;
 
 extern int exception_trace;
-extern int using_apic_timer;
-extern int disable_apic;
 extern unsigned cpu_khz;
-extern int ioapic_force;
-extern int skip_ioapic_setup;
-extern int acpi_ht;
-extern int acpi_disabled;
 
 extern void no_iommu_init(void);
 extern int force_iommu, no_iommu;
 
 extern int reboot_force;
 extern int notsc_setup(char *);
-extern int setup_additional_cpus(char *);
 
 extern void smp_local_timer_interrupt(struct pt_regs * regs);