os-k/boot/loader/cpu/cpuid.inc

71 lines
4.1 KiB
PHP

;=----------------------------------------------------------------------------=;
; GNU GPL OS/K ;
; ;
; Desc: Basic realmode CPU Detection ;
; (x86_64 architecture only) ;
; ;
; ;
; Copyright © 2018-2019 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]
; ---------------------------------------------------------------------------- ;
; 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