diff options
author | hpa <hpa> | 2002-04-28 05:40:11 +0000 |
---|---|---|
committer | hpa <hpa> | 2002-04-28 05:40:11 +0000 |
commit | bdb0fcf1acccec785084bfe0b3802d4674638b64 (patch) | |
tree | bfe06e9b601affd91f3e028a3e274dc05a668c13 /cpuinit.inc | |
parent | c0cd85e0e93e2390f3f33169c78e4ed0033e5ceb (diff) | |
download | syslinux-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.inc | 106 |
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 + + |