123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
- MODULE MemCache; (** AUTHOR "pjm"; PURPOSE "Memory cache control"; *)
- IMPORT SYSTEM, Machine;
- CONST
- (** cache properties *)
- UC* = 0; WC* = 1; WT* = 4; WP* = 5; WB* = 6;
- PS = 4096; (* page size in bytes *)
- M = 100000H; (* 1K, 1M, 1G *)
- Ok = 0;
- TYPE
- SetCacheMessage = POINTER TO RECORD (Machine.Message)
- physAdr: ADDRESS; size, type: LONGINT;
- res: ARRAY Machine.MaxCPU OF WORD
- END;
- (* Return the value of the MTTRcap register. *)
- PROCEDURE -GetMTTRcapLow(): SET;
- CODE
- #IF I386 THEN
- MOV ECX, 0FEH ; MTTRcap
- RDMSR
- #ELSIF AMD64 THEN
- XOR RAX, RAX
- MOV ECX, 0FEH ; MTTRcap
- RDMSR
- #ELSE
- unimplemented
- #END
- END GetMTTRcapLow;
- (*
- (* Return the value of the MTTRdefType register. *)
- PROCEDURE -GetMTTRdefTypeLow(): SET;
- CODE
- #IF I386 THEN
- MOV ECX, 2FFH ; MTTRdefType
- RDMSR
- #ELSIF AMD64 THEN
- XOR RAX, RAX
- MOV ECX, 2FFH ; MTTRdefType
- RDMSR
- #ELSE
- unimplemented
- #END
- END GetMTTRdefTypeLow;
- *)
- (* Return the value of the specified MTTRphysBase register. *)
- PROCEDURE -GetMTTRphysBaseLow(n: ADDRESS): SET;
- CODE
- #IF I386 THEN
- POP ECX
- SHL ECX, 1
- ADD ECX, 200H ; MTTRphysBase0
- RDMSR
- #ELSIF AMD64 THEN
- XOR RAX, RAX
- POP RCX
- SHL RCX, 1
- ADD RCX, 200H ; MTTRphysBase0
- RDMSR
- #ELSE
- unimplemented
- #END
- END GetMTTRphysBaseLow;
- (* Return the value of the specified MTTRphysMask register. *)
- PROCEDURE -GetMTTRphysMaskLow(n: ADDRESS): SET;
- CODE
- #IF I386 THEN
- POP ECX
- SHL ECX, 1
- ADD ECX, 201H ; MTTRphysMask0
- RDMSR
- #ELSIF AMD64 THEN
- XOR RAX, RAX
- POP RCX
- SHL RCX, 1
- ADD RCX, 201H ; MTTRphysMask0
- RDMSR
- #ELSE
- unimplemented
- #END
- END GetMTTRphysMaskLow;
- (* Set the specified MTTRphysBase register. *)
- PROCEDURE -SetMTTRphysBase(n: ADDRESS; high, low: SET);
- CODE
- #IF I386 THEN
- POP EAX
- POP EDX
- POP ECX
- SHL ECX, 1
- ADD ECX, 200H ; MTTRphysBase0
- WRMSR
- #ELSIF AMD64 THEN
- POP RAX
- POP RDX
- POP RCX
- SHL RCX, 1
- ADD RCX, 200H ; MTTRphysBase0
- WRMSR
- #ELSE
- unimplemented
- #END
- END SetMTTRphysBase;
- (* Set the specified MTTRphysMask register. *)
- PROCEDURE -SetMTTRphysMask(n: ADDRESS; high, low: SET);
- CODE
- #IF I386 THEN
- POP EAX
- POP EDX
- POP ECX
- SHL ECX, 1
- ADD ECX, 201H ; MTTRphysMask0
- WRMSR
- #ELSIF AMD64 THEN
- POP RAX
- POP RDX
- POP RCX
- SHL RCX, 1
- ADD RCX, 201H ; MTTRphysMask0
- WRMSR
- #ELSE
- unimplemented
- #END
- END SetMTTRphysMask;
- (** Set the cache properties of the specified physical memory area on the current processor. {physAdr, size MOD PS = 0} Must be called from supervisor mode. *)
- PROCEDURE LocalSetCacheProperties*(physAdr: ADDRESS; size, type: LONGINT; VAR res: WORD);
- VAR i, n, f: LONGINT; mask, base: SET; j, k: ADDRESS;
- BEGIN
- ASSERT((physAdr MOD PS = 0) & (size MOD PS = 0) & (size # 0));
- IF (physAdr >= M) OR (physAdr < 0) THEN
- k := size; WHILE k > 0 DO k := ASH(k, 1) END; (* shift highest set bit into bit 31 *)
- IF k = 80000000H THEN (* only one bit was set => size is power of 2 *)
- IF physAdr MOD size = 0 THEN
- Machine.Acquire(Machine.Memory); (* hack *)
- IF Machine.MTTR IN Machine.features THEN (* MTTRs supported *)
- mask := GetMTTRcapLow();
- IF (type # WC) OR (10 IN mask) THEN
- n := SYSTEM.VAL(LONGINT, mask * {0..7});
- i := 0; f := -1; res := Ok;
- WHILE (i # n) & (res = Ok) DO
- mask := GetMTTRphysMaskLow(i);
- IF 11 IN mask THEN (* entry is valid *)
- mask := mask * {12..MAX(SET)};
- base := GetMTTRphysBaseLow(i) * mask;
- j := physAdr; k := physAdr+size;
- WHILE (j # k) & (SYSTEM.VAL(SET, j) * mask # base) DO INC(j, PS) END; (* performance! *)
- IF j # k THEN res := 1508 END (* cache type of region already set *)
- ELSE
- IF f = -1 THEN f := i END (* first free entry *)
- END;
- INC(i)
- END;
- IF res = Ok THEN
- IF f # -1 THEN
- SetMTTRphysBase(f, {}, SYSTEM.VAL(SET, physAdr) * {12..31} + SYSTEM.VAL(SET, type) * {0..7});
- SetMTTRphysMask(f, {0..3}, (-SYSTEM.VAL(SET, size-1)) * {12..31} + {11})
- ELSE
- res := 1506 (* out of cache control entries *)
- END
- ELSE
- (* skip *)
- END
- ELSE
- res := 1511 (* region type not supported *)
- END
- ELSE
- res := 1505 (* MTTRs not supported *)
- END;
- Machine.Release(Machine.Memory)
- ELSE
- res := 1510 (* region base must be aligned on size *)
- END
- ELSE
- res := 1509 (* region size must be power of 2 *)
- END
- ELSE
- res := 1507 (* implementation restriction - fixed entries not supported *)
- END
- END LocalSetCacheProperties;
- PROCEDURE HandleSetCacheProperties(id: LONGINT; CONST state: Machine.State; msg: Machine.Message);
- BEGIN
- WITH msg: SetCacheMessage DO
- (* to do: page 11-25 *)
- LocalSetCacheProperties(msg.physAdr, msg.size, msg.type, msg.res[id])
- END
- END HandleSetCacheProperties;
- (** Broadcast a LocalSetCacheProperties operation to all processors. *)
- PROCEDURE GlobalSetCacheProperties*(physAdr: ADDRESS; size, type: LONGINT; VAR res: WORD);
- VAR i: LONGINT; msg: SetCacheMessage;
- BEGIN
- NEW(msg); msg.physAdr := physAdr; msg.size := size; msg.type := type;
- FOR i := 0 TO Machine.MaxCPU-1 DO msg.res[i] := 2304 END; (* default result *)
- Machine.Broadcast(HandleSetCacheProperties, msg, {Machine.Self, Machine.FrontBarrier, Machine.BackBarrier});
- res := 0;
- FOR i := 0 TO Machine.MaxCPU-1 DO
- IF (res = 0) & (msg.res[i] # 0) THEN res := msg.res[i] END (* return first non-ok result found *)
- END
- END GlobalSetCacheProperties;
- (** Disable all caching on the current processor. *)
- PROCEDURE LocalDisableCaching*;
- CODE {SYSTEM.Pentium, SYSTEM.Privileged}
- PUSHFD
- CLI
- MOV EAX, CR0
- OR EAX, 40000000H
- AND EAX, 0DFFFFFFFH
- MOV CR0, EAX
- WBINVD
- MOV EAX, CR4
- AND EAX, 0FFFFFF7FH
- MOV CR4, EAX
- MOV EAX, CR3
- MOV CR3, EAX
- MOV ECX, 2FFH ; MTTRdefType
- MOV EAX, 0
- MOV EDX, 0
- WRMSR
- WBINVD
- MOV EAX, CR3
- MOV CR3, EAX
- MOV EAX, CR0
- OR EAX, 60000000H
- MOV CR0, EAX
- POPFD
- END LocalDisableCaching;
- PROCEDURE HandleDisableCaching(id: LONGINT; CONST state: Machine.State; msg: Machine.Message);
- BEGIN
- LocalDisableCaching
- END HandleDisableCaching;
- (** Broadcast a LocalDisableCaching operation to all processors. *)
- PROCEDURE GlobalDisableCaching*;
- BEGIN
- Machine.Broadcast(HandleDisableCaching, NIL, {Machine.Self, Machine.FrontBarrier, Machine.BackBarrier})
- END GlobalDisableCaching;
- END MemCache.
- (*
- to do:
- o change error codes
- *)
|