1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <amdblocks/cpu.h>
4 #include <amdblocks/iomap.h>
5 #include <assert.h>
6 #include <cpu/amd/mtrr.h>
7 #include <cpu/x86/cache.h>
8 #include <cpu/x86/msr.h>
9 #include <cpu/x86/mtrr.h>
10 #include <soc/iomap.h>
11 #include <stdint.h>
12
13 /* Allocate a static amount of stack for the MTRR context. */
14 #define MAX_VAR_MTRR_USE 10
15
16 /*
17 * PSP performs the memory training and setting up DRAM map prior to x86 cores being released.
18 * Honor TOP_MEM and set up caching from 0 til TOP_MEM. Likewise, route lower memory addresses
19 * covered by fixed MTRRs to DRAM except for 0xa0000-0xc0000.
20 */
early_cache_setup(void)21 void early_cache_setup(void)
22 {
23 msr_t sys_cfg;
24 msr_t mtrr_def_type;
25 msr_t fixed_mtrr_ram;
26 msr_t fixed_mtrr_mmio;
27 union mtrr_ctx {
28 struct var_mtrr_context ctx;
29 char buffer[sizeof(struct var_mtrr_context)
30 + 2 * MAX_VAR_MTRR_USE * sizeof(msr_t)];
31
32 } mtrr_ctx;
33
34 var_mtrr_context_init(&mtrr_ctx.ctx);
35 mtrr_ctx.ctx.max_var_mtrrs = MIN(MAX_VAR_MTRR_USE, mtrr_ctx.ctx.max_var_mtrrs);
36 /* Enable RdDram and WrDram attributes in fixed MTRRs. */
37 sys_cfg = rdmsr(SYSCFG_MSR);
38 sys_cfg.lo |= SYSCFG_MSR_MtrrFixDramModEn;
39
40 /* Fixed MTRR constants. */
41 fixed_mtrr_ram.lo = fixed_mtrr_ram.hi =
42 ((MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM) << 0) |
43 ((MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM) << 8) |
44 ((MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM) << 16) |
45 ((MTRR_TYPE_WRBACK | MTRR_READ_MEM | MTRR_WRITE_MEM) << 24);
46 fixed_mtrr_mmio.lo = fixed_mtrr_mmio.hi =
47 ((MTRR_TYPE_UNCACHEABLE) << 0) |
48 ((MTRR_TYPE_UNCACHEABLE) << 8) |
49 ((MTRR_TYPE_UNCACHEABLE) << 16) |
50 ((MTRR_TYPE_UNCACHEABLE) << 24);
51
52 /* Prep default MTRR type. */
53 mtrr_def_type = rdmsr(MTRR_DEF_TYPE_MSR);
54 mtrr_def_type.lo &= ~MTRR_DEF_TYPE_MASK;
55 mtrr_def_type.lo |= MTRR_TYPE_UNCACHEABLE;
56 mtrr_def_type.lo |= MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN;
57
58 disable_cache();
59
60 wrmsr(SYSCFG_MSR, sys_cfg);
61
62 var_mtrr_set(&mtrr_ctx.ctx, 0, ALIGN_DOWN(get_top_of_mem_below_4gb(), 8 * MiB),
63 MTRR_TYPE_WRBACK);
64 /* Always mark the 16 MByte right below the 4 GB boundary as WRPROT */
65 var_mtrr_set(&mtrr_ctx.ctx, FLASH_BELOW_4GB_MAPPING_REGION_BASE,
66 FLASH_BELOW_4GB_MAPPING_REGION_SIZE, MTRR_TYPE_WRPROT);
67
68 commit_mtrr_setup(&mtrr_ctx.ctx);
69
70 /* Set up RAM caching for everything below 1MiB except for 0xa0000-0xc0000 . */
71 wrmsr(MTRR_FIX_64K_00000, fixed_mtrr_ram);
72 wrmsr(MTRR_FIX_16K_80000, fixed_mtrr_ram);
73 wrmsr(MTRR_FIX_16K_A0000, fixed_mtrr_mmio);
74 wrmsr(MTRR_FIX_4K_C0000, fixed_mtrr_ram);
75 wrmsr(MTRR_FIX_4K_C8000, fixed_mtrr_ram);
76 wrmsr(MTRR_FIX_4K_D0000, fixed_mtrr_ram);
77 wrmsr(MTRR_FIX_4K_D8000, fixed_mtrr_ram);
78 wrmsr(MTRR_FIX_4K_E0000, fixed_mtrr_ram);
79 wrmsr(MTRR_FIX_4K_E8000, fixed_mtrr_ram);
80 wrmsr(MTRR_FIX_4K_F0000, fixed_mtrr_ram);
81 wrmsr(MTRR_FIX_4K_F8000, fixed_mtrr_ram);
82
83 wrmsr(MTRR_DEF_TYPE_MSR, mtrr_def_type);
84
85 /* Enable Fixed and Variable MTRRs. */
86 sys_cfg.lo |= SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn;
87 sys_cfg.lo |= SYSCFG_MSR_TOM2En | SYSCFG_MSR_TOM2WB;
88 /* AGESA currently expects SYSCFG_MSR_MtrrFixDramModEn to be set. Once
89 MP init happens in coreboot proper it can be knocked down. */
90 wrmsr(SYSCFG_MSR, sys_cfg);
91
92 enable_cache();
93 }
94