summaryrefslogtreecommitdiff
path: root/cpuinit.inc
diff options
context:
space:
mode:
authorhpa <hpa>2002-04-28 05:40:11 +0000
committerhpa <hpa>2002-04-28 05:40:11 +0000
commitbdb0fcf1acccec785084bfe0b3802d4674638b64 (patch)
treebfe06e9b601affd91f3e028a3e274dc05a668c13 /cpuinit.inc
parentc0cd85e0e93e2390f3f33169c78e4ed0033e5ceb (diff)
downloadsyslinux-bdb0fcf1acccec785084bfe0b3802d4674638b64.tar.gz
Factor out CPU initialization and some common configuration intosyslinux-1.73-pre6
separate files; fix bcopy bugs.
Diffstat (limited to 'cpuinit.inc')
-rw-r--r--cpuinit.inc106
1 files changed, 106 insertions, 0 deletions
diff --git a/cpuinit.inc b/cpuinit.inc
new file mode 100644
index 00000000..a6923b54
--- /dev/null
+++ b/cpuinit.inc
@@ -0,0 +1,106 @@
+;; $Id$
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+;; Bostom MA 02111-1307, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; cpuinit.inc
+;;
+;; CPU-dependent initialization and related checks.
+;;
+
+;
+; Check that no moron is trying to boot Linux on a 286 or so. According
+; to Intel, the way to check is to see if the high 4 bits of the FLAGS
+; register are either all stuck at 1 (8086/8088) or all stuck at 0
+; (286 in real mode), if not it is a 386 or higher. They didn't
+; say how to check for a 186/188, so I *hope* it falls out as a 8086
+; or 286 in this test.
+;
+; Also, provide an escape route in case it doesn't work.
+;
+check_escapes:
+ mov ah,02h ; Check keyboard flags
+ int 16h
+ mov [KbdFlags],al ; Save for boot prompt check
+ test al,04h ; Ctrl->skip 386 check
+ jnz skip_checks
+test_8086:
+ pushf ; Get flags
+ pop ax
+ and ax,0FFFh ; Clear top 4 bits
+ push ax ; Load into FLAGS
+ popf
+ pushf ; And load back
+ pop ax
+ and ax,0F000h ; Get top 4 bits
+ cmp ax,0F000h ; If set -> 8086/8088
+ je not_386
+test_286:
+ pushf ; Get flags
+ pop ax
+ or ax,0F000h ; Set top 4 bits
+ push ax
+ popf
+ pushf
+ pop ax
+ and ax,0F000h ; Get top 4 bits
+ jnz is_386 ; If not clear -> 386
+not_386:
+ mov si,err_not386
+ call writestr
+ jmp kaboom
+is_386:
+ ; Now we know it's a 386 or higher
+;
+; Now check that there is sufficient low (DOS) memory
+;
+ int 12h
+ cmp ax,(real_mode_seg+0xa00) >> 6
+ jae enough_ram
+ mov si,err_noram
+ call writestr
+ jmp kaboom
+enough_ram:
+skip_checks:
+
+;
+; Check if we're 386 (as opposed to 486+); if so we need to blank out
+; the WBINVD instruction
+;
+; We check for 486 by setting EFLAGS.AC
+;
+%if DO_WBINVD
+ pushfd ; Save the good flags
+ pushfd
+ pop eax
+ mov ebx,eax
+ xor eax,(1 << 18) ; AC bit
+ push eax
+ popfd
+ pushfd
+ pop eax
+ popfd ; Restore the original flags
+ xor eax,ebx
+ jnz is_486
+;
+; 386 - Looks like we better blot out the WBINVD instruction
+;
+ mov byte [try_wbinvd],0c3h ; Near RET
+is_486:
+%endif ; DO_WBINVD
+;
+; Mark A20 type as unknown. This particular word needs to be in BSS,
+; so it needs to be initialized.
+;
+ mov word [A20Type],0
+
+