car.S 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright (c) 2014 Google, Inc
  3. *
  4. * From Coreboot file cpu/intel/model_206ax/cache_as_ram.inc
  5. *
  6. * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
  7. * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
  8. * Copyright (C) 2007-2008 coresystems GmbH
  9. * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
  10. *
  11. * SPDX-License-Identifier: GPL-2.0
  12. */
  13. #include <common.h>
  14. #include <asm/microcode.h>
  15. #include <asm/msr-index.h>
  16. #include <asm/mtrr.h>
  17. #include <asm/post.h>
  18. #include <asm/processor.h>
  19. #include <asm/processor-flags.h>
  20. #define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
  21. #define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
  22. #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
  23. #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
  24. /* Cache 4GB - MRC_SIZE_KB for MRC */
  25. #define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
  26. #define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
  27. #define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
  28. #define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
  29. #define NOEVICTMOD_MSR 0x2e0
  30. /*
  31. * Note: ebp must not be touched in this code as it holds the BIST
  32. * value (built-in self test). We preserve this value until it can
  33. * be written to global_data when CAR is ready for use.
  34. */
  35. .globl car_init
  36. car_init:
  37. post_code(POST_CAR_START)
  38. /* Send INIT IPI to all excluding ourself */
  39. movl $0x000C4500, %eax
  40. movl $0xFEE00300, %esi
  41. movl %eax, (%esi)
  42. /* TODO: Load microcode later - the 'no eviction' mode breaks this */
  43. movl $MSR_IA32_UCODE_WRITE, %ecx
  44. xorl %edx, %edx
  45. movl $_dt_ucode_base_size, %eax
  46. movl (%eax), %eax
  47. addl $UCODE_HEADER_LEN, %eax
  48. wrmsr
  49. post_code(POST_CAR_SIPI)
  50. /* Zero out all fixed range and variable range MTRRs */
  51. movl $mtrr_table, %esi
  52. movl $((mtrr_table_end - mtrr_table) / 2), %edi
  53. xorl %eax, %eax
  54. xorl %edx, %edx
  55. clear_mtrrs:
  56. movw (%esi), %bx
  57. movzx %bx, %ecx
  58. wrmsr
  59. add $2, %esi
  60. dec %edi
  61. jnz clear_mtrrs
  62. post_code(POST_CAR_MTRR)
  63. /* Configure the default memory type to uncacheable */
  64. movl $MTRR_DEF_TYPE_MSR, %ecx
  65. rdmsr
  66. andl $(~0x00000cff), %eax
  67. wrmsr
  68. post_code(POST_CAR_UNCACHEABLE)
  69. /* Set Cache-as-RAM base address */
  70. movl $(MTRR_PHYS_BASE_MSR(0)), %ecx
  71. movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
  72. xorl %edx, %edx
  73. wrmsr
  74. post_code(POST_CAR_BASE_ADDRESS)
  75. /* Set Cache-as-RAM mask */
  76. movl $(MTRR_PHYS_MASK_MSR(0)), %ecx
  77. movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
  78. movl $CPU_PHYSMASK_HI, %edx
  79. wrmsr
  80. post_code(POST_CAR_MASK)
  81. /* Enable MTRR */
  82. movl $MTRR_DEF_TYPE_MSR, %ecx
  83. rdmsr
  84. orl $MTRR_DEF_TYPE_EN, %eax
  85. wrmsr
  86. /* Enable cache (CR0.CD = 0, CR0.NW = 0) */
  87. movl %cr0, %eax
  88. andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
  89. invd
  90. movl %eax, %cr0
  91. /* enable the 'no eviction' mode */
  92. movl $NOEVICTMOD_MSR, %ecx
  93. rdmsr
  94. orl $1, %eax
  95. andl $~2, %eax
  96. wrmsr
  97. /* Clear the cache memory region. This will also fill up the cache */
  98. movl $CACHE_AS_RAM_BASE, %esi
  99. movl %esi, %edi
  100. movl $(CACHE_AS_RAM_SIZE / 4), %ecx
  101. xorl %eax, %eax
  102. rep stosl
  103. /* enable the 'no eviction run' state */
  104. movl $NOEVICTMOD_MSR, %ecx
  105. rdmsr
  106. orl $3, %eax
  107. wrmsr
  108. post_code(POST_CAR_FILL)
  109. /* Enable Cache-as-RAM mode by disabling cache */
  110. movl %cr0, %eax
  111. orl $X86_CR0_CD, %eax
  112. movl %eax, %cr0
  113. /* Enable cache for our code in Flash because we do XIP here */
  114. movl $MTRR_PHYS_BASE_MSR(1), %ecx
  115. xorl %edx, %edx
  116. movl $car_init_ret, %eax
  117. andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
  118. orl $MTRR_TYPE_WRPROT, %eax
  119. wrmsr
  120. movl $MTRR_PHYS_MASK_MSR(1), %ecx
  121. movl $CPU_PHYSMASK_HI, %edx
  122. movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
  123. wrmsr
  124. post_code(POST_CAR_ROM_CACHE)
  125. #ifdef CONFIG_CACHE_MRC_BIN
  126. /* Enable caching for ram init code to run faster */
  127. movl $MTRR_PHYS_BASE_MSR(2), %ecx
  128. movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
  129. xorl %edx, %edx
  130. wrmsr
  131. movl $MTRR_PHYS_MASK_MSR(2), %ecx
  132. movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
  133. movl $CPU_PHYSMASK_HI, %edx
  134. wrmsr
  135. #endif
  136. post_code(POST_CAR_MRC_CACHE)
  137. /* Enable cache */
  138. movl %cr0, %eax
  139. andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
  140. movl %eax, %cr0
  141. post_code(POST_CAR_CPU_CACHE)
  142. /* All CPUs need to be in Wait for SIPI state */
  143. wait_for_sipi:
  144. movl (%esi), %eax
  145. bt $12, %eax
  146. jc wait_for_sipi
  147. /* return */
  148. jmp car_init_ret
  149. .globl car_uninit
  150. car_uninit:
  151. /* Disable cache */
  152. movl %cr0, %eax
  153. orl $X86_CR0_CD, %eax
  154. movl %eax, %cr0
  155. /* Disable MTRRs */
  156. movl $MTRR_DEF_TYPE_MSR, %ecx
  157. rdmsr
  158. andl $(~MTRR_DEF_TYPE_EN), %eax
  159. wrmsr
  160. /* Disable the no-eviction run state */
  161. movl $NOEVICTMOD_MSR, %ecx
  162. rdmsr
  163. andl $~2, %eax
  164. wrmsr
  165. invd
  166. /* Disable the no-eviction mode */
  167. rdmsr
  168. andl $~1, %eax
  169. wrmsr
  170. #ifdef CONFIG_CACHE_MRC_BIN
  171. /* Clear the MTRR that was used to cache MRC */
  172. xorl %eax, %eax
  173. xorl %edx, %edx
  174. movl $MTRR_PHYS_BASE_MSR(2), %ecx
  175. wrmsr
  176. movl $MTRR_PHYS_MASK_MSR(2), %ecx
  177. wrmsr
  178. #endif
  179. /* Enable MTRRs */
  180. movl $MTRR_DEF_TYPE_MSR, %ecx
  181. rdmsr
  182. orl $MTRR_DEF_TYPE_EN, %eax
  183. wrmsr
  184. invd
  185. ret
  186. mtrr_table:
  187. /* Fixed MTRRs */
  188. .word 0x250, 0x258, 0x259
  189. .word 0x268, 0x269, 0x26A
  190. .word 0x26B, 0x26C, 0x26D
  191. .word 0x26E, 0x26F
  192. /* Variable MTRRs */
  193. .word 0x200, 0x201, 0x202, 0x203
  194. .word 0x204, 0x205, 0x206, 0x207
  195. .word 0x208, 0x209, 0x20A, 0x20B
  196. .word 0x20C, 0x20D, 0x20E, 0x20F
  197. .word 0x210, 0x211, 0x212, 0x213
  198. mtrr_table_end:
  199. .align 4
  200. _dt_ucode_base_size:
  201. /* These next two fields are filled in by ifdtool */
  202. .globl ucode_base
  203. ucode_base: /* Declared in microcode.h */
  204. .long 0 /* microcode base */
  205. .long 0 /* microcode size */