0

So I want to check if protected and long mode is supported while being in real mode. I know that I can check for support of long mode while being in protected mode, but that requires cpuid instruction which I don't think we have in real mode (at least in old processors).

I didn't found any information about that.

  • 3
    If your processor has the cpuid instruction, you can execute it in any mode, including real mode. As for checking if the cpuid instruction is present, that's already answered in detail in other questions. – fuz Jan 25 '23 at 12:07
  • 3
    See [this](https://web.archive.org/web/20220817022152/http://www.rcollins.org/ddj/Sep96/Sep96.html). You can detect the 8088/8086, 80286, 80386 and 80486 (with and without the `cpuid` inst) with `pushf/popf`. Once you know the CPU supports `cpuid` (which can go back as the 486) then you know you have protected mode (which goes back to the 286/386 depending on your definition). – Margaret Bloom Jan 25 '23 at 12:53
  • In this question I have code that does these kinds of checks to make sure you have a 386, processor has CPUID and that the processor supports long mode. https://stackoverflow.com/q/57436125/3857942 – Michael Petch Jan 25 '23 at 17:39

1 Answers1

6

A full sequence might be:

1.1) Determine if the CPU is an actual 8086 chip by testing if bit 15 of the flags register is set. If you don't do this the next step can cause the CPU to crash.

1.2) Determine if the CPU supports 32 bit by testing if the IOPL flags (bits 12 and 13 of FLAGS register) can be modified. If you don't do this the next step can cause the CPU to crash

1.3) Check if the ID flag (bit 21 of eflags register) can be modified. If it can be modified the CPU supports the CPUID instruction. Note that it's fine to use 32-bit instructions in real mode (to push and pop eflags) if the CPU supports 32-bit instructions.

Note 1: From memory; there were some CPUs (NexGen from National Semiconductor) that support CPUID but don't support Intel's "ID flag" method; and there are some CPUs (from Cyrix and IBM) where the CPUID instruction needs to be enabled before it can be used (via. special IO ports). Dealing with these CPUs is possible, but beyond the scope of my answer.

Note 2: As an alternative; if you know it isn't an 8086, you can install an invalid opcode exception handler and try to execute a CPUID instruction. If your invalid opcode exception handler is called then CPUID currently isn't supported.

2.1) Use "CPUID with EAX=0x80000000" to determine if CPUID supports "CPUID with EAX=0x80000001". This step is just a sanity check in case the CPU returns unknown information (e.g. from the highest CPUID function supported) from unsupported CPUID functions.

2.2) Use "CPUID with EAX=0x80000001" to get (AMD's) extended feature flags. Test bit 29 in EDX to determine if long mode is supported.

Note 3: For UEFI boot loaders you can always assume CPUID is supported (e.g. for 32-bit UEFI). For 64-bit UEFI you can skip all of it (you're already using long mode so it must be supported).

Brendan
  • 35,656
  • 2
  • 39
  • 66