#ifdef CONFIG_X86_32
# include <linux/ctype.h>
# include <linux/mc146818rtc.h>
+ + # include <asm/realmode.h>
#else
# include <asm/x86_init.h>
#endif
enum reboot_type reboot_type = BOOT_ACPI;
int reboot_force;
- - /* This variable is used privately to keep track of whether or not
+ + /*
+ + * This variable is used privately to keep track of whether or not
* reboot_type is still set to its default value (i.e., reboot= hasn't
* been set on the command line). This is needed so that we can
* suppress DMI scanning for reboot quirks. Without it, it's
static int reboot_cpu = -1;
#endif
- - /* This is set if we need to go through the 'emergency' path.
+ + /*
+ + * This is set if we need to go through the 'emergency' path.
* When machine_emergency_restart() is called, we may be on
* an inconsistent state and won't be able to do a clean cleanup
*/
/* This is set by the PCI code if either type 1 or type 2 PCI is detected */
bool port_cf9_safe = false;
- - /* reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
- - warm Don't set the cold reboot flag
- - cold Set the cold reboot flag
- - bios Reboot by jumping through the BIOS (only for X86_32)
- - smp Reboot by executing reset on BSP or other CPU (only for X86_32)
- - triple Force a triple fault (init)
- - kbd Use the keyboard controller. cold reset (default)
- - acpi Use the RESET_REG in the FADT
- - efi Use efi reset_system runtime service
- - pci Use the so-called "PCI reset register", CF9
- - force Avoid anything that could hang.
+ + /*
+ + * reboot=b[ios] | s[mp] | t[riple] | k[bd] | e[fi] [, [w]arm | [c]old] | p[ci]
+ + * warm Don't set the cold reboot flag
+ + * cold Set the cold reboot flag
+ + * bios Reboot by jumping through the BIOS (only for X86_32)
+ + * smp Reboot by executing reset on BSP or other CPU (only for X86_32)
+ + * triple Force a triple fault (init)
+ + * kbd Use the keyboard controller. cold reset (default)
+ + * acpi Use the RESET_REG in the FADT
+ + * efi Use efi reset_system runtime service
+ + * pci Use the so-called "PCI reset register", CF9
+ + * force Avoid anything that could hang.
*/
static int __init reboot_setup(char *str)
{
for (;;) {
- - /* Having anything passed on the command line via
+ + /*
+ + * Having anything passed on the command line via
* reboot= will cause us to disable DMI checking
* below.
*/
if (isdigit(*(str+2)))
reboot_cpu = reboot_cpu*10 + (int)(*(str+2) - '0');
}
- - /* we will leave sorting out the final value
- - when we are ready to reboot, since we might not
- - have detected BSP APIC ID or smp_num_cpu */
+ + /*
+ + * We will leave sorting out the final value
+ + * when we are ready to reboot, since we might not
+ + * have detected BSP APIC ID or smp_num_cpu
+ + */
break;
#endif /* CONFIG_SMP */
return 0;
}
+ + void machine_real_restart(unsigned int type)
+ + {
+ + void (*restart_lowmem)(unsigned int) = (void (*)(unsigned int))
+ + real_mode_header->machine_real_restart_asm;
+ +
+ + local_irq_disable();
+ +
+ + /*
+ + * Write zero to CMOS register number 0x0f, which the BIOS POST
+ + * routine will recognize as telling it to do a proper reboot. (Well
+ + * that's what this book in front of me says -- it may only apply to
+ + * the Phoenix BIOS though, it's not clear). At the same time,
+ + * disable NMIs by setting the top bit in the CMOS address register,
+ + * as we're about to do peculiar things to the CPU. I'm not sure if
+ + * `outb_p' is needed instead of just `outb'. Use it to be on the
+ + * safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
+ + */
+ + spin_lock(&rtc_lock);
+ + CMOS_WRITE(0x00, 0x8f);
+ + spin_unlock(&rtc_lock);
+ +
+ + /*
+ + * Switch back to the initial page table.
+ + */
+ + load_cr3(initial_page_table);
+ +
+ + /*
+ + * Write 0x1234 to absolute memory location 0x472. The BIOS reads
+ + * this on booting to tell it to "Bypass memory test (also warm
+ + * boot)". This seems like a fairly standard thing that gets set by
+ + * REBOOT.COM programs, and the previous reset routine did this
+ + * too. */
+ + *((unsigned short *)0x472) = reboot_mode;
+ +
+ + /* Jump to the identity-mapped low memory code */
+ + restart_lowmem(type);
+ + }
+ + #ifdef CONFIG_APM_MODULE
+ + EXPORT_SYMBOL(machine_real_restart);
+ + #endif
+ +
+ + #endif /* CONFIG_X86_32 */
+ +
+ + /*
+ + * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
+ + */
+ + static int __init set_pci_reboot(const struct dmi_system_id *d)
+ + {
+ + if (reboot_type != BOOT_CF9) {
+ + reboot_type = BOOT_CF9;
+ + printk(KERN_INFO "%s series board detected. "
+ + "Selecting PCI-method for reboots.\n", d->ident);
+ + }
+ + return 0;
+ + }
+ +
static int __init set_kbd_reboot(const struct dmi_system_id *d)
{
if (reboot_type != BOOT_KBD) {
return 0;
}
+ + /*
+ + * This is a single dmi_table handling all reboot quirks. Note that
+ + * REBOOT_BIOS is only available for 32bit
+ + */
static struct dmi_system_id __initdata reboot_dmi_table[] = {
+ + #ifdef CONFIG_X86_32
{ /* Handle problems with rebooting on Dell E520's */
.callback = set_bios_reboot,
.ident = "Dell E520",
DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
},
},
- - { /* Handle problems with rebooting on Dell Optiplex 745's SFF*/
+ + { /* Handle problems with rebooting on Dell Optiplex 745's SFF */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 745",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
},
},
- - { /* Handle problems with rebooting on Dell Optiplex 745's DFF*/
+ + { /* Handle problems with rebooting on Dell Optiplex 745's DFF */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 745",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "0MM599"),
},
},
- - { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
+ + { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 745",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "0KW626"),
},
},
- - { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
+ + { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 330",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
},
},
- - { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
+ + { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 360",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
},
},
- - { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G*/
+ + { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */
.callback = set_bios_reboot,
.ident = "Dell OptiPlex 760",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "SBC-FITPC2"),
},
},
- - { /* Handle problems with rebooting on ASUS P4S800 */
+ + { /* Handle problems with rebooting on ASUS P4S800 */
.callback = set_bios_reboot,
.ident = "ASUS P4S800",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
},
},
- - { /* Handle reboot issue on Acer Aspire one */
+ + #endif /* CONFIG_X86_32 */
+ +
+ + { /* Handle reboot issue on Acer Aspire one */
.callback = set_kbd_reboot,
.ident = "Acer Aspire One A110",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
},
},
- - { }
- - };
- -
- - static int __init reboot_init(void)
- - {
- - /* Only do the DMI check if reboot_type hasn't been overridden
- - * on the command line
- - */
- - if (reboot_default) {
- - dmi_check_system(reboot_dmi_table);
- - }
- - return 0;
- - }
- - core_initcall(reboot_init);
- -
- - extern const unsigned char machine_real_restart_asm[];
- - extern const u64 machine_real_restart_gdt[3];
- -
- - void machine_real_restart(unsigned int type)
- - {
- - void *restart_va;
- - unsigned long restart_pa;
- - void (*restart_lowmem)(unsigned int);
- - u64 *lowmem_gdt;
- -
- - local_irq_disable();
- -
- - /* Write zero to CMOS register number 0x0f, which the BIOS POST
- - routine will recognize as telling it to do a proper reboot. (Well
- - that's what this book in front of me says -- it may only apply to
- - the Phoenix BIOS though, it's not clear). At the same time,
- - disable NMIs by setting the top bit in the CMOS address register,
- - as we're about to do peculiar things to the CPU. I'm not sure if
- - `outb_p' is needed instead of just `outb'. Use it to be on the
- - safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
- - */
- - spin_lock(&rtc_lock);
- - CMOS_WRITE(0x00, 0x8f);
- - spin_unlock(&rtc_lock);
- -
- - /*
- - * Switch back to the initial page table.
- - */
- - load_cr3(initial_page_table);
- -
- - /* Write 0x1234 to absolute memory location 0x472. The BIOS reads
- - this on booting to tell it to "Bypass memory test (also warm
- - boot)". This seems like a fairly standard thing that gets set by
- - REBOOT.COM programs, and the previous reset routine did this
- - too. */
- - *((unsigned short *)0x472) = reboot_mode;
- -
- - /* Patch the GDT in the low memory trampoline */
- - lowmem_gdt = TRAMPOLINE_SYM(machine_real_restart_gdt);
- -
- - restart_va = TRAMPOLINE_SYM(machine_real_restart_asm);
- - restart_pa = virt_to_phys(restart_va);
- - restart_lowmem = (void (*)(unsigned int))restart_pa;
- -
- - /* GDT[0]: GDT self-pointer */
- - lowmem_gdt[0] =
- - (u64)(sizeof(machine_real_restart_gdt) - 1) +
- - ((u64)virt_to_phys(lowmem_gdt) << 16);
- - /* GDT[1]: 64K real mode code segment */
- - lowmem_gdt[1] =
- - GDT_ENTRY(0x009b, restart_pa, 0xffff);
- -
- - /* Jump to the identity-mapped low memory code */
- - restart_lowmem(type);
- - }
- - #ifdef CONFIG_APM_MODULE
- - EXPORT_SYMBOL(machine_real_restart);
- - #endif
- -
- - #endif /* CONFIG_X86_32 */
- -
- - /*
- - * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
- - */
- - static int __init set_pci_reboot(const struct dmi_system_id *d)
- - {
- - if (reboot_type != BOOT_CF9) {
- - reboot_type = BOOT_CF9;
- - printk(KERN_INFO "%s series board detected. "
- - "Selecting PCI-method for reboots.\n", d->ident);
- - }
- - return 0;
- - }
- -
- - static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
{ /* Handle problems with rebooting on Apple MacBook5 */
.callback = set_pci_reboot,
.ident = "Apple MacBook5",
DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
},
},
++++ { /* Handle problems with rebooting on the Precision M6600. */
++++ .callback = set_pci_reboot,
++++ .ident = "Dell OptiPlex 990",
++++ .matches = {
++++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++++ DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
++++ },
++++ },
{ }
};
- - static int __init pci_reboot_init(void)
+ + static int __init reboot_init(void)
{
- - /* Only do the DMI check if reboot_type hasn't been overridden
+ + /*
+ + * Only do the DMI check if reboot_type hasn't been overridden
* on the command line
*/
- - if (reboot_default) {
- - dmi_check_system(pci_reboot_dmi_table);
- - }
+ + if (reboot_default)
+ + dmi_check_system(reboot_dmi_table);
return 0;
}
- - core_initcall(pci_reboot_init);
+ + core_initcall(reboot_init);
static inline void kb_wait(void)
{
cpu_emergency_vmxoff();
}
- - /* Use NMIs as IPIs to tell all CPUs to disable virtualization
- - */
+ + /* Use NMIs as IPIs to tell all CPUs to disable virtualization */
static void emergency_vmx_disable_all(void)
{
/* Just make sure we won't change CPUs while doing this */
local_irq_disable();
- - /* We need to disable VMX on all CPUs before rebooting, otherwise
+ + /*
+ + * We need to disable VMX on all CPUs before rebooting, otherwise
* we risk hanging up the machine, because the CPU ignore INIT
* signals when VMX is enabled.
*
* is still enabling VMX.
*/
if (cpu_has_vmx() && cpu_vmx_enabled()) {
- - /* Disable VMX on this CPU.
- - */
+ + /* Disable VMX on this CPU. */
cpu_vmxoff();
/* Halt and disable VMX on the other CPUs */
/* Could also try the reset bit in the Hammer NB */
switch (reboot_type) {
case BOOT_KBD:
- - mach_reboot_fixups(); /* for board specific fixups */
+ + mach_reboot_fixups(); /* For board specific fixups */
for (i = 0; i < 10; i++) {
kb_wait();
udelay(50);
- - outb(0xfe, 0x64); /* pulse reset low */
+ + outb(0xfe, 0x64); /* Pulse reset low */
udelay(50);
}
if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
case BOOT_CF9:
port_cf9_safe = true;
- - /* fall through */
+ + /* Fall through */
case BOOT_CF9_COND:
if (port_cf9_safe) {
/* Make certain I only run on the appropriate processor */
set_cpus_allowed_ptr(current, cpumask_of(reboot_cpu_id));
- - /* O.K Now that I'm on the appropriate processor,
- - * stop all of the others.
+ + /*
- * O.K Now that I'm on the appropriate processor,
- * stop all of the others.
+ + + * O.K Now that I'm on the appropriate processor, stop all of the
+ + + * others. Also disable the local irq to not receive the per-cpu
+ + + * timer interrupt which may trigger scheduler's load balance.
*/
+ + + local_irq_disable();
stop_other_cpus();
#endif
static void native_machine_halt(void)
{
- - /* stop other cpus and apics */
+ + /* Stop other cpus and apics */
machine_shutdown();
tboot_shutdown(TB_SHUTDOWN_HALT);
- - /* stop this cpu */
stop_this_cpu(NULL);
}
machine_shutdown();
pm_power_off();
}
- - /* a fallback in case there is no PM info available */
+ + /* A fallback in case there is no PM info available */
tboot_shutdown(TB_SHUTDOWN_HALT);
}
cpu = raw_smp_processor_id();
- - /* Don't do anything if this handler is invoked on crashing cpu.
+ + /*
+ + * Don't do anything if this handler is invoked on crashing cpu.
* Otherwise, system will completely hang. Crashing cpu can get
* an NMI if system was initially booted with nmi_watchdog parameter.
*/
apic->send_IPI_allbutself(NMI_VECTOR);
}
- - /* Halt all other CPUs, calling the specified function on each of them
+ + /*
+ + * Halt all other CPUs, calling the specified function on each of them
*
* This function can be used to halt all other CPUs on crash
* or emergency reboot time. The function passed as parameter
unsigned long msecs;
local_irq_disable();
- - /* Make a note of crashing cpu. Will be used in NMI callback.*/
+ + /* Make a note of crashing cpu. Will be used in NMI callback. */
crashing_cpu = safe_smp_processor_id();
shootdown_callback = callback;
/* Would it be better to replace the trap vector here? */
if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
NMI_FLAG_FIRST, "crash"))
- - return; /* return what? */
- - /* Ensure the new callback function is set before sending
+ + return; /* Return what? */
+ + /*
+ + * Ensure the new callback function is set before sending
* out the NMI
*/
wmb();