use BIOS settings (if it already configured) for MTRRs

git-svn-id: svn://kolibrios.org@1030 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Evgeny Grechnikov (Diamond) 2009-02-11 23:20:18 +00:00
parent fb8dc89b4d
commit 54be51b2aa

View File

@ -1168,41 +1168,52 @@ proc init_mtrr
mov ecx, 0x2FF mov ecx, 0x2FF
rdmsr ; rdmsr ;
; has BIOS already initialized MTRRs?
test ah, 8
jnz .skip_init
; rarely needed, so mainly placeholder
; main memory - cached
push eax push eax
xor edx, edx
xor eax, eax
mov ecx, 0x2FF
wrmsr ;disable all MTRR
mov eax, [MEM_AMOUNT] mov eax, [MEM_AMOUNT]
; round eax up to next power of 2 ; round eax up to next power of 2
dec eax dec eax
bsr ecx, eax bsr ecx, eax
mov eax, 2 mov ebx, 2
shl eax, cl shl ebx, cl
stdcall set_mtrr, edx,edx,eax,MEM_WB dec ebx
stdcall set_mtrr, 1,[LFBAddress],[LFBSize],MEM_WC ; base of memory range = 0, type of memory range = MEM_WB
xor edx, edx xor edx, edx
xor eax, eax mov eax, MEM_WB
mov ecx, 0x204 mov ecx, 0x200
mov ebx, 6 wrmsr
@@: ; mask of memory range = 0xFFFFFFFFF - (size - 1), ebx = size - 1
wrmsr ;disable unused MTRR mov eax, 0xFFFFFFFF
mov edx, 0x0000000F
sub eax, ebx
sbb edx, 0
or eax, 0x800
inc ecx inc ecx
wrmsr wrmsr
; clear unused MTRRs
xor eax, eax
xor edx, edx
@@:
wrmsr
inc ecx inc ecx
dec ebx cmp ecx, 0x210
jnz @b jb @b
; enable MTRRs
pop eax
or ah, 8
and al, 0xF0 ; default memtype = UC
mov ecx, 0x2FF
wrmsr
.skip_init:
stdcall set_mtrr, [LFBAddress],[LFBSize],MEM_WC
wbinvd ;again invalidate wbinvd ;again invalidate
pop eax
or eax, 0x800 ;set default memtype to UC
and al, 0xF0
mov ecx, 0x2FF
wrmsr ;and enable MTRR
mov eax, cr0 mov eax, cr0
and eax, not 0x60000000 and eax, not 0x60000000
mov cr0, eax ; enable caching mov cr0, eax ; enable caching
@ -1211,13 +1222,29 @@ proc init_mtrr
endp endp
align 4 align 4
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword proc set_mtrr stdcall, base:dword,size:dword,mem_type:dword
; find unused register
mov ecx, 0x201
@@:
rdmsr
dec ecx
test ah, 8
jz .found
rdmsr
mov al, 0 ; clear memory type field
cmp eax, [base]
jz .ret
add ecx, 3
cmp ecx, 0x210
jb @b
; no free registers, ignore the call
.ret:
ret
.found:
; found, write values
xor edx, edx xor edx, edx
mov eax, [base] mov eax, [base]
or eax, [mem_type] or eax, [mem_type]
mov ecx, [reg]
lea ecx, [0x200+ecx*2]
wrmsr wrmsr
mov ebx, [size] mov ebx, [size]