patch-2.4.22 linux-2.4.22/arch/x86_64/kernel/warmreboot.S
Next file: linux-2.4.22/arch/x86_64/mm/fault.c
Previous file: linux-2.4.22/arch/x86_64/kernel/traps.c
Back to the patch index
Back to the overall index
- Lines: 84
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/x86_64/kernel/warmreboot.S
- Orig date:
1969-12-31 16:00:00.000000000 -0800
diff -urN linux-2.4.21/arch/x86_64/kernel/warmreboot.S linux-2.4.22/arch/x86_64/kernel/warmreboot.S
@@ -0,0 +1,83 @@
+/*
+ * Switch back to real mode and call the BIOS reboot vector.
+ * This is a trampoline copied around in process.c
+ * Written 2003 by Andi Kleen, SuSE Labs.
+ */
+
+#include <asm/msr.h>
+
+#define R(x) x-warm_reboot(%ebx)
+#define R64(x) x-warm_reboot(%rbx)
+
+ /* running in identity mapping and in the first 64k of memory
+ and in compatibility mode. This must be position independent */
+
+ /* Follows 14.7 "Leaving Long Mode" in the AMD x86-64 manual, volume 2
+ and 8.9.2 "Switching Back to Real-Address Mode" in the Intel IA32
+ manual, volume 2 */
+
+ /* ebx: self pointer to warm_reboot */
+
+ .globl warm_reboot
+warm_reboot:
+ addl %ebx, R64(real_mode_desc) /* relocate tables */
+ addl %ebx,2+R64(warm_gdt_desc)
+
+ movq %cr0,%rax
+ btr $31,%rax
+ movq %rax,%cr0 /* disable paging */
+ jmp 1f /* flush prefetch queue */
+
+ .code32
+1: movl $MSR_EFER,%ecx
+ rdmsr
+ andl $~((1<<_EFER_LME)|(1<<_EFER_SCE)|(1<<_EFER_NX)),%eax
+ wrmsr /* disable long mode in EFER */
+
+ xorl %eax,%eax
+ movl %eax,%cr3 /* flush tlb */
+
+ /* Running protected mode without paging now */
+
+ wbinvd /* flush caches. Needed? */
+
+ lidt R(warm_idt_desc)
+ lgdt R(warm_gdt_desc)
+
+ movl $0x10,%ecx /* load segment registers with real mode settings */
+ movl %ecx,%ds
+ movl %ecx,%es
+ movl %ecx,%fs
+ movl %ecx,%gs
+ movl %ecx,%ss
+
+ lea R(real_mode_desc),%eax
+ ljmp *(%eax)
+
+ .code16:
+real_mode:
+ xorl %eax,%eax
+ movl %eax,%cr0
+
+ /* some people claim $0xf000,0xfff0 is better. Use what 32bit linux uses. */
+ /* code as bytes because gas has problems with it */
+ .byte 0xea,0xf0,0xff,0x00,0xf0 /* ljmp 0xf000:0xfff0 */
+
+real_mode_desc:
+ .long real_mode - warm_reboot
+ .short 8
+warm_gdt_desc:
+ .short 8*3
+ .long warm_gdt - warm_reboot
+warm_gdt:
+ .quad 0
+ .quad 0x00009a000000ffff /* 16-bit real-mode 64k code at 0x00000000 */
+ .quad 0x000092000100ffff /* 16-bit real-mode 64k data at 0x00000100 */
+
+warm_idt_desc:
+ .short 0x3ff
+ .long 0
+
+ .globl warm_reboot_end
+warm_reboot_end:
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)