| 1 | /* $NetBSD: biosreboot.S,v 1.4 2005/12/11 12:17:48 christos Exp $ */
|
|---|
| 2 |
|
|---|
| 3 | /*
|
|---|
| 4 | * Copyright (c) 1997
|
|---|
| 5 | * Perry E. Metzger. All rights reserved.
|
|---|
| 6 | *
|
|---|
| 7 | * Redistribution and use in source and binary forms, with or without
|
|---|
| 8 | * modification, are permitted provided that the following conditions
|
|---|
| 9 | * are met:
|
|---|
| 10 | * 1. Redistributions of source code must retain the above copyright
|
|---|
| 11 | * notice, this list of conditions and the following disclaimer.
|
|---|
| 12 | * 2. Redistributions in binary form must reproduce the above copyright
|
|---|
| 13 | * notice, this list of conditions and the following disclaimer in the
|
|---|
| 14 | * documentation and/or other materials provided with the distribution.
|
|---|
| 15 | * 3. All advertising materials mentioning features or use of this software
|
|---|
| 16 | * must display the following acknowledgements:
|
|---|
| 17 | * This product includes software developed for the NetBSD Project
|
|---|
| 18 | * by Perry E. Metzger.
|
|---|
| 19 | * 4. The names of the authors may not be used to endorse or promote products
|
|---|
| 20 | * derived from this software without specific prior written permission.
|
|---|
| 21 | *
|
|---|
| 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|---|
| 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|---|
| 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|---|
| 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|---|
| 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|---|
| 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|---|
| 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|---|
| 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|---|
| 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|---|
| 31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|---|
| 32 | *
|
|---|
| 33 | */
|
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 | #include <machine/asm.h>
|
|---|
| 37 |
|
|---|
| 38 | .text
|
|---|
| 39 |
|
|---|
| 40 | .set BDA_BOOT,0x472 /* Boot howto flag location */
|
|---|
| 41 |
|
|---|
| 42 | /*
|
|---|
| 43 | * Reboot the system via the BIOS.
|
|---|
| 44 | */
|
|---|
| 45 | ENTRY(reboot)
|
|---|
| 46 | pushl %ebp
|
|---|
| 47 | movl %esp,%ebp
|
|---|
| 48 | pushl %ebx
|
|---|
| 49 | push %esi
|
|---|
| 50 | push %edi
|
|---|
| 51 |
|
|---|
| 52 | call _C_LABEL(prot_to_real)
|
|---|
| 53 | .code16
|
|---|
| 54 |
|
|---|
| 55 | /*
|
|---|
| 56 | * We don't want to use INT 19 for reboot because it isn't
|
|---|
| 57 | * guaranteed to work, and besides it is what the BIOS itself
|
|---|
| 58 | * calls _after_ a successful completion of the POST routines.
|
|---|
| 59 | *
|
|---|
| 60 | * From the IBM PC BIOS documentation:
|
|---|
| 61 | *
|
|---|
| 62 | * "INT 19 - SYSTEM - BOOTSTRAP LOADER
|
|---|
| 63 | *
|
|---|
| 64 | * "This interrupt reboots the system without clearing memory
|
|---|
| 65 | * or restoring interrupt vectors. Because interrupt vectors
|
|---|
| 66 | * are preserved, this interrupt usually causes a system hang
|
|---|
| 67 | * if any TSRs have hooked vectors from 00h through 1Ch,
|
|---|
| 68 | * particularly INT 08.
|
|---|
| 69 | *
|
|---|
| 70 | * "To accomplish a warm boot equivalent to Ctrl-Alt-Del,
|
|---|
| 71 | * store 1234h in 0040h:0072h and jump to FFFFh:0000h. For a
|
|---|
| 72 | * cold boot equivalent to a reset, store 0000h at 0040h:0072h
|
|---|
| 73 | * before jumping."
|
|---|
| 74 | *
|
|---|
| 75 | * Note: Unfortunately both warm and cold boot on VirtualBox
|
|---|
| 76 | * (since at least 4.0.4 through to at least 4.1.8) hang the
|
|---|
| 77 | * (virtual) system. What does seem to work on VirtualBox,
|
|---|
| 78 | * from the kernel, is the PC/AT Control Port A Fast Reset.
|
|---|
| 79 | * (PCI-bus system & CPU reset does not work.)
|
|---|
| 80 | *
|
|---|
| 81 | * From the Linux kernel:
|
|---|
| 82 | *
|
|---|
| 83 | * "Write zero to CMOS register number 0x0f, which the BIOS
|
|---|
| 84 | * POST routine will recognize as telling it to do a proper
|
|---|
| 85 | * reboot. (Well that's what this book in front of me says --
|
|---|
| 86 | * it may only apply to the Phoenix BIOS though, it's not
|
|---|
| 87 | * clear). At the same time, disable NMIs by setting the top
|
|---|
| 88 | * bit in the CMOS address register, as we're about to do
|
|---|
| 89 | * peculiar things to the CPU."
|
|---|
| 90 | *
|
|---|
| 91 | * outb_p (0x8f, 0x70);
|
|---|
| 92 | * outb_p (0x00, 0x71);
|
|---|
| 93 | *
|
|---|
| 94 | * For now we will try what the BIOS folks call a "cold boot"
|
|---|
| 95 | * (it's actually a form of warm boot, since it does not
|
|---|
| 96 | * trigger a hardware reset) since this will ensure the most
|
|---|
| 97 | * complete reset of system state is done without actually
|
|---|
| 98 | * causing a hardware reset.
|
|---|
| 99 | */
|
|---|
| 100 | movw $0x0000, BDA_BOOT /* set cold boot (clear warm boot flag) */
|
|---|
| 101 | /*
|
|---|
| 102 | * XXX apparently this would only be correct for an original 8086:
|
|---|
| 103 | *
|
|---|
| 104 | ljmp $0xffff, $0x0000
|
|---|
| 105 | */
|
|---|
| 106 | /*
|
|---|
| 107 | * "however in various literature it is mentioned that
|
|---|
| 108 | * $0xf000,$0xfff0 is bound to work better..."
|
|---|
| 109 | *
|
|---|
| 110 | * http://unix.derkeiler.com/Mailing-Lists/FreeBSD/hackers/2003-11/0205.html
|
|---|
| 111 | *
|
|---|
| 112 | * "Apparently CPUs haven't started with the CS:IP combination
|
|---|
| 113 | * FFFF:0000 since the 8086. The 80286 changed this to
|
|---|
| 114 | * F000:FFF0.
|
|---|
| 115 | *
|
|---|
| 116 | * "32-bit CPUs start up in what is colloquially known as
|
|---|
| 117 | * unreal mode. Even though the initial value of the CS
|
|---|
| 118 | * register after reset is F000, the segment descriptor
|
|---|
| 119 | * associated with that register initially holds FFFF0000 as
|
|---|
| 120 | * its base address. So the physical address that initially
|
|---|
| 121 | * corresponds to the the 16:16 CS:IP address F000:FFF0 is in
|
|---|
| 122 | * fact, and has been since the days of the 80386, FFFFFFF0.
|
|---|
| 123 | * And that's where the machine firmware is principally mapped
|
|---|
| 124 | * into physical address space on 32-bit and 64-bit x86
|
|---|
| 125 | * machines."
|
|---|
| 126 | *
|
|---|
| 127 | * http://superuser.com/questions/336021/is-bios-read-from-the-bios-chip-or-copied-into-ram-on-startup
|
|---|
| 128 | *
|
|---|
| 129 | * Since we are in 16-bit "real" mode, we can use the 16:16
|
|---|
| 130 | * address here.
|
|---|
| 131 | *
|
|---|
| 132 | * There's also a story that one should never try to reset the
|
|---|
| 133 | * CPU without enabling CPU A20 to the address BUS.
|
|---|
| 134 | *
|
|---|
| 135 | * http://www.rcollins.org/Productivity/A20Reset.html
|
|---|
| 136 | *
|
|---|
| 137 | * See here for doing this:
|
|---|
| 138 | *
|
|---|
| 139 | * http://www.brokenthorn.com/Resources/OSDev9.html
|
|---|
| 140 | *
|
|---|
| 141 | * However others say "the CPU restart vector on 286 and above
|
|---|
| 142 | * processors is not F000:FFF0. These CPUs actually execute
|
|---|
| 143 | * out of the very top of their physical address space, which
|
|---|
| 144 | * in some cases is occupied by a [special] boot loader...
|
|---|
| 145 | * Even though the CPU is executing out of memory above the
|
|---|
| 146 | * 1MB address mark, it is still executing in real mode, not
|
|---|
| 147 | * protected mode (really, real mode). Once the CS register is
|
|---|
| 148 | * reloaded with any value, the CPU disables the upper address
|
|---|
| 149 | * lines and, typically, continues to execute at the
|
|---|
| 150 | * 8086-compatible reboot address, F000:FFF0".
|
|---|
| 151 | *
|
|---|
| 152 | * NOTE: Apparently on some machines there will be an INT 19h
|
|---|
| 153 | * instruction here, while others will jump to the main BIOS
|
|---|
| 154 | * entry point (e.g. f000:e05b).
|
|---|
| 155 | *
|
|---|
| 156 | * Jump to the BIOS "Power On Reset Vector":
|
|---|
| 157 | */
|
|---|
| 158 | ljmp $0xf000, $0xfff0
|
|---|
| 159 |
|
|---|
| 160 | /* NOTE: We will never get here.... */
|
|---|
| 161 |
|
|---|
| 162 | calll _C_LABEL(real_to_prot)
|
|---|
| 163 | .code32
|
|---|
| 164 |
|
|---|
| 165 | movl %ebx, %eax
|
|---|
| 166 |
|
|---|
| 167 | pop %edi
|
|---|
| 168 | pop %esi
|
|---|
| 169 | popl %ebx
|
|---|
| 170 | popl %ebp
|
|---|
| 171 | ret
|
|---|