car.S 5.5 KB

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