BIOS.MemCache.Mod 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE MemCache; (** AUTHOR "pjm"; PURPOSE "Memory cache control"; *)
  3. IMPORT SYSTEM, Machine;
  4. CONST
  5. (** cache properties *)
  6. UC* = 0; WC* = 1; WT* = 4; WP* = 5; WB* = 6;
  7. PS = 4096; (* page size in bytes *)
  8. M = 100000H; (* 1K, 1M, 1G *)
  9. Ok = 0;
  10. TYPE
  11. SetCacheMessage = POINTER TO RECORD (Machine.Message)
  12. physAdr: ADDRESS; size, type: LONGINT;
  13. res: ARRAY Machine.MaxCPU OF WORD
  14. END;
  15. (* Return the value of the MTTRcap register. *)
  16. PROCEDURE -GetMTTRcapLow(): SET;
  17. CODE
  18. #IF I386 THEN
  19. MOV ECX, 0FEH ; MTTRcap
  20. RDMSR
  21. #ELSIF AMD64 THEN
  22. XOR RAX, RAX
  23. MOV ECX, 0FEH ; MTTRcap
  24. RDMSR
  25. #ELSE
  26. unimplemented
  27. #END
  28. END GetMTTRcapLow;
  29. (*
  30. (* Return the value of the MTTRdefType register. *)
  31. PROCEDURE -GetMTTRdefTypeLow(): SET;
  32. CODE
  33. #IF I386 THEN
  34. MOV ECX, 2FFH ; MTTRdefType
  35. RDMSR
  36. #ELSIF AMD64 THEN
  37. XOR RAX, RAX
  38. MOV ECX, 2FFH ; MTTRdefType
  39. RDMSR
  40. #ELSE
  41. unimplemented
  42. #END
  43. END GetMTTRdefTypeLow;
  44. *)
  45. (* Return the value of the specified MTTRphysBase register. *)
  46. PROCEDURE -GetMTTRphysBaseLow(n: ADDRESS): SET;
  47. CODE
  48. #IF I386 THEN
  49. POP ECX
  50. SHL ECX, 1
  51. ADD ECX, 200H ; MTTRphysBase0
  52. RDMSR
  53. #ELSIF AMD64 THEN
  54. XOR RAX, RAX
  55. POP RCX
  56. SHL RCX, 1
  57. ADD RCX, 200H ; MTTRphysBase0
  58. RDMSR
  59. #ELSE
  60. unimplemented
  61. #END
  62. END GetMTTRphysBaseLow;
  63. (* Return the value of the specified MTTRphysMask register. *)
  64. PROCEDURE -GetMTTRphysMaskLow(n: ADDRESS): SET;
  65. CODE
  66. #IF I386 THEN
  67. POP ECX
  68. SHL ECX, 1
  69. ADD ECX, 201H ; MTTRphysMask0
  70. RDMSR
  71. #ELSIF AMD64 THEN
  72. XOR RAX, RAX
  73. POP RCX
  74. SHL RCX, 1
  75. ADD RCX, 201H ; MTTRphysMask0
  76. RDMSR
  77. #ELSE
  78. unimplemented
  79. #END
  80. END GetMTTRphysMaskLow;
  81. (* Set the specified MTTRphysBase register. *)
  82. PROCEDURE -SetMTTRphysBase(n: ADDRESS; high, low: SET);
  83. CODE
  84. #IF I386 THEN
  85. POP EAX
  86. POP EDX
  87. POP ECX
  88. SHL ECX, 1
  89. ADD ECX, 200H ; MTTRphysBase0
  90. WRMSR
  91. #ELSIF AMD64 THEN
  92. POP RAX
  93. POP RDX
  94. POP RCX
  95. SHL RCX, 1
  96. ADD RCX, 200H ; MTTRphysBase0
  97. WRMSR
  98. #ELSE
  99. unimplemented
  100. #END
  101. END SetMTTRphysBase;
  102. (* Set the specified MTTRphysMask register. *)
  103. PROCEDURE -SetMTTRphysMask(n: ADDRESS; high, low: SET);
  104. CODE
  105. #IF I386 THEN
  106. POP EAX
  107. POP EDX
  108. POP ECX
  109. SHL ECX, 1
  110. ADD ECX, 201H ; MTTRphysMask0
  111. WRMSR
  112. #ELSIF AMD64 THEN
  113. POP RAX
  114. POP RDX
  115. POP RCX
  116. SHL RCX, 1
  117. ADD RCX, 201H ; MTTRphysMask0
  118. WRMSR
  119. #ELSE
  120. unimplemented
  121. #END
  122. END SetMTTRphysMask;
  123. (** 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. *)
  124. PROCEDURE LocalSetCacheProperties*(physAdr: ADDRESS; size, type: LONGINT; VAR res: WORD);
  125. VAR i, n, f: LONGINT; mask, base: SET; j, k: ADDRESS;
  126. BEGIN
  127. ASSERT((physAdr MOD PS = 0) & (size MOD PS = 0) & (size # 0));
  128. IF (physAdr >= M) OR (physAdr < 0) THEN
  129. k := size; WHILE k > 0 DO k := ASH(k, 1) END; (* shift highest set bit into bit 31 *)
  130. IF k = 80000000H THEN (* only one bit was set => size is power of 2 *)
  131. IF physAdr MOD size = 0 THEN
  132. Machine.Acquire(Machine.Memory); (* hack *)
  133. IF Machine.MTTR IN Machine.features THEN (* MTTRs supported *)
  134. mask := GetMTTRcapLow();
  135. IF (type # WC) OR (10 IN mask) THEN
  136. n := SYSTEM.VAL(LONGINT, mask * {0..7});
  137. i := 0; f := -1; res := Ok;
  138. WHILE (i # n) & (res = Ok) DO
  139. mask := GetMTTRphysMaskLow(i);
  140. IF 11 IN mask THEN (* entry is valid *)
  141. mask := mask * {12..MAX(SET)};
  142. base := GetMTTRphysBaseLow(i) * mask;
  143. j := physAdr; k := physAdr+size;
  144. WHILE (j # k) & (SYSTEM.VAL(SET, j) * mask # base) DO INC(j, PS) END; (* performance! *)
  145. IF j # k THEN res := 1508 END (* cache type of region already set *)
  146. ELSE
  147. IF f = -1 THEN f := i END (* first free entry *)
  148. END;
  149. INC(i)
  150. END;
  151. IF res = Ok THEN
  152. IF f # -1 THEN
  153. SetMTTRphysBase(f, {}, SYSTEM.VAL(SET, physAdr) * {12..31} + SYSTEM.VAL(SET, type) * {0..7});
  154. SetMTTRphysMask(f, {0..3}, (-SYSTEM.VAL(SET, size-1)) * {12..31} + {11})
  155. ELSE
  156. res := 1506 (* out of cache control entries *)
  157. END
  158. ELSE
  159. (* skip *)
  160. END
  161. ELSE
  162. res := 1511 (* region type not supported *)
  163. END
  164. ELSE
  165. res := 1505 (* MTTRs not supported *)
  166. END;
  167. Machine.Release(Machine.Memory)
  168. ELSE
  169. res := 1510 (* region base must be aligned on size *)
  170. END
  171. ELSE
  172. res := 1509 (* region size must be power of 2 *)
  173. END
  174. ELSE
  175. res := 1507 (* implementation restriction - fixed entries not supported *)
  176. END
  177. END LocalSetCacheProperties;
  178. PROCEDURE HandleSetCacheProperties(id: LONGINT; CONST state: Machine.State; msg: Machine.Message);
  179. BEGIN
  180. WITH msg: SetCacheMessage DO
  181. (* to do: page 11-25 *)
  182. LocalSetCacheProperties(msg.physAdr, msg.size, msg.type, msg.res[id])
  183. END
  184. END HandleSetCacheProperties;
  185. (** Broadcast a LocalSetCacheProperties operation to all processors. *)
  186. PROCEDURE GlobalSetCacheProperties*(physAdr: ADDRESS; size, type: LONGINT; VAR res: WORD);
  187. VAR i: LONGINT; msg: SetCacheMessage;
  188. BEGIN
  189. NEW(msg); msg.physAdr := physAdr; msg.size := size; msg.type := type;
  190. FOR i := 0 TO Machine.MaxCPU-1 DO msg.res[i] := 2304 END; (* default result *)
  191. Machine.Broadcast(HandleSetCacheProperties, msg, {Machine.Self, Machine.FrontBarrier, Machine.BackBarrier});
  192. res := 0;
  193. FOR i := 0 TO Machine.MaxCPU-1 DO
  194. IF (res = 0) & (msg.res[i] # 0) THEN res := msg.res[i] END (* return first non-ok result found *)
  195. END
  196. END GlobalSetCacheProperties;
  197. (** Disable all caching on the current processor. *)
  198. PROCEDURE LocalDisableCaching*;
  199. CODE {SYSTEM.Pentium, SYSTEM.Privileged}
  200. PUSHFD
  201. CLI
  202. MOV EAX, CR0
  203. OR EAX, 40000000H
  204. AND EAX, 0DFFFFFFFH
  205. MOV CR0, EAX
  206. WBINVD
  207. MOV EAX, CR4
  208. AND EAX, 0FFFFFF7FH
  209. MOV CR4, EAX
  210. MOV EAX, CR3
  211. MOV CR3, EAX
  212. MOV ECX, 2FFH ; MTTRdefType
  213. MOV EAX, 0
  214. MOV EDX, 0
  215. WRMSR
  216. WBINVD
  217. MOV EAX, CR3
  218. MOV CR3, EAX
  219. MOV EAX, CR0
  220. OR EAX, 60000000H
  221. MOV CR0, EAX
  222. POPFD
  223. END LocalDisableCaching;
  224. PROCEDURE HandleDisableCaching(id: LONGINT; CONST state: Machine.State; msg: Machine.Message);
  225. BEGIN
  226. LocalDisableCaching
  227. END HandleDisableCaching;
  228. (** Broadcast a LocalDisableCaching operation to all processors. *)
  229. PROCEDURE GlobalDisableCaching*;
  230. BEGIN
  231. Machine.Broadcast(HandleDisableCaching, NIL, {Machine.Self, Machine.FrontBarrier, Machine.BackBarrier})
  232. END GlobalDisableCaching;
  233. END MemCache.
  234. (*
  235. to do:
  236. o change error codes
  237. *)