コード例 #1
0
ファイル: reboot.c プロジェクト: robcore/machinex
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);
}
コード例 #2
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);
}