Rick C. Hodgin
2019-06-19 15:25:20 UTC
In my custom OS kernel, I use this code to enter protected mode:
cli ; Clear interrupts
mov eax,cr0
or al,1
mov cr0,eax
;; Ok, we're in protected mode, still 16-bit code segment though
jmp $+2 ; Clear the cache
lidt fword ptr IDT_ptr ; Load IDT
lgdt fword ptr GDT_ptr ; Load GDT
xor ax,ax
lldt ax ; Load LDT with NULL
mov ax,_sTSS ; Load TR
ltr ax
; Data segment registers
mov ax,_sDATA
mov ds,ax
mov es,ax
; Extra segment registers
mov ax,_sVGA
mov fs,ax
mov ax,_sMONO
mov gs,ax
; Stack
mov ax,_sSTACK
mov ss,ax
mov esp,_sSTACK_limit - 4
sti
After this I push the new target address on the stack and issue
a RETF to go there.
On the line above after the ";; Ok, we're in protected mode..."
I issue a JMP $+2. I remember when writing this code that it was
a requirement to clear the cache.
-----
My question today is ... why does that need to be done? Is it
only because the pre-decoded instructions are operating in the
legacy sense of the prior real-mode decoding engine? And now
they need to be re-decoded using the protected-mode decoding
scheme?
And if so, would it be possible to put enough NOP instructions
after the MOV CR0,EAX instruction where it enters protected mode
to cause the CPU to never need a JMP instruction to clear the
cache because the NOPs would simply flood-fill it and it would
automatically decode future cache line reads using the new mode?
I don't see any practical use for this knowledge, but I'm more
curious than anything.
cli ; Clear interrupts
mov eax,cr0
or al,1
mov cr0,eax
;; Ok, we're in protected mode, still 16-bit code segment though
jmp $+2 ; Clear the cache
lidt fword ptr IDT_ptr ; Load IDT
lgdt fword ptr GDT_ptr ; Load GDT
xor ax,ax
lldt ax ; Load LDT with NULL
mov ax,_sTSS ; Load TR
ltr ax
; Data segment registers
mov ax,_sDATA
mov ds,ax
mov es,ax
; Extra segment registers
mov ax,_sVGA
mov fs,ax
mov ax,_sMONO
mov gs,ax
; Stack
mov ax,_sSTACK
mov ss,ax
mov esp,_sSTACK_limit - 4
sti
After this I push the new target address on the stack and issue
a RETF to go there.
On the line above after the ";; Ok, we're in protected mode..."
I issue a JMP $+2. I remember when writing this code that it was
a requirement to clear the cache.
-----
My question today is ... why does that need to be done? Is it
only because the pre-decoded instructions are operating in the
legacy sense of the prior real-mode decoding engine? And now
they need to be re-decoded using the protected-mode decoding
scheme?
And if so, would it be possible to put enough NOP instructions
after the MOV CR0,EAX instruction where it enters protected mode
to cause the CPU to never need a JMP instruction to clear the
cache because the NOPs would simply flood-fill it and it would
automatically decode future cache line reads using the new mode?
I don't see any practical use for this knowledge, but I'm more
curious than anything.
--
Rick C. Hodgin
Rick C. Hodgin