72 lines
4.1 KiB
PHP
72 lines
4.1 KiB
PHP
;=----------------------------------------------------------------------------=;
|
|
; OS on Kaleid ;
|
|
; ;
|
|
; Desc: Basic realmode CPU Detection ;
|
|
; (x86_64 architecture only) ;
|
|
; ;
|
|
; ;
|
|
; Copyright © 2018-2021 The OS/K Team ;
|
|
; ;
|
|
; This file is part of OS/K. ;
|
|
; ;
|
|
; OS/K 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, either version 3 of the License, or ;
|
|
; (at your option) any later version. ;
|
|
; ;
|
|
; OS/K is distributed in the hope that it will be useful, ;
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of ;
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;
|
|
; GNU General Public License for more details. ;
|
|
; ;
|
|
; You should have received a copy of the GNU General Public License ;
|
|
; along with OS/K. If not, see <https://www.gnu.org/licenses/>. ;
|
|
;=----------------------------------------------------------------------------=;
|
|
|
|
[BITS 32]
|
|
[section .text]
|
|
|
|
; ---------------------------------------------------------------------------- ;
|
|
; Checks if the CPU is compatible with 64-bits operating systems ;
|
|
; If the 21th bit of the eax register is set, then CPUID is supported ;
|
|
; We then test CPUID's result to see if long mode is supported ;
|
|
; ---------------------------------------------------------------------------- ;
|
|
Is64Bits:
|
|
;; test if extended processor info in available
|
|
mov eax, 0x80000000 ; implicit argument for cpuid
|
|
cpuid ; get highest supported argument
|
|
cmp eax, 0x80000001 ; it needs to be at least 0x80000001
|
|
jb .no_64 ; if it's less, the CPU is too old for long mode
|
|
|
|
;; use extended info to test if long mode is available
|
|
mov eax, 0x80000001 ; argument for extended processor info
|
|
cpuid ; returns various feature bits in ecx and edx
|
|
test edx, 1 << 29 ; test if the LM-bit is set in the D-register
|
|
jz .no_64 ; If it's not set, there is no long mode
|
|
ret
|
|
.no_64:
|
|
mov ax, "03" ; ERROR 03 : 64bits unsupported
|
|
jmp Error
|
|
|
|
; ---------------------------------------------------------------------------- ;
|
|
; Check if CPUID is supported by flip the bit 21 (ID bit) in the FLAGS ;
|
|
; register. If we can flip, CPUID is available. ;
|
|
; ---------------------------------------------------------------------------- ;
|
|
Check_cpuid:
|
|
pushfd ; Copy FLAGS in to EAX via stack
|
|
pop eax
|
|
mov ecx, eax ; Copy to ECX as well for comparing later on
|
|
xor eax, 1 << 21 ; Flip the ID bit
|
|
push eax ; Copy EAX to FLAGS via the stack
|
|
popfd
|
|
pushfd ; Copy FLAGS back to EAX (with the flipped bit if CPUID is supported)
|
|
pop eax
|
|
push ecx ; flipping the flipped ID bit back if it was ever flipped like flipper
|
|
popfd
|
|
cmp eax, ecx ; VERITY MOMENT
|
|
je .no_cpuid
|
|
ret
|
|
.no_cpuid:
|
|
mov ax, "02" ; ERROR 02 : CPUID UNSUPPORTED
|
|
jmp Error
|