1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include <commonlib/bsd/ipchksum.h>
4 #include <console/console.h>
5 #include <cpu/cpu.h>
6 #include <cpu/x86/mtrr.h>
7 #include <intelbasecode/ramtop.h>
8 #include <pc80/mc146818rtc.h>
9 #include <stdint.h>
10
11 /* We need a region in CMOS to store the RAMTOP address */
12
13 #define RAMTOP_SIGNATURE 0x52544F50 /* 'RTOP' */
14
15 /*
16 * Address of the ramtop byte in CMOS. Should be reserved
17 * in mainboards' cmos.layout and not covered by checksum.
18 */
19
20 #if CONFIG(USE_OPTION_TABLE)
21 #include "option_table.h"
22
23 #ifndef CMOS_VSTART_ramtop
24 #error "The `ramtop` CMOS entry is missing, please add it to your cmos.layout."
25 #endif
26
27 #if CMOS_VSTART_ramtop % 8 != 0
28 #error "The `ramtop` CMOS entry needs to be byte aligned, check your cmos.layout."
29 #endif // CMOS_VSTART_ramtop % 8 != 0
30
31 #if CMOS_VLEN_ramtop != (10 * 8)
32 #error "The `ramtop` CMOS entry needs to be 10 bytes long, check your cmos.layout."
33 #endif // CMOS_VLEN_ramtop != (10 * 8)
34
35 #else
36 #define CMOS_VSTART_ramtop 800
37 #endif // CONFIG(USE_OPTION_TABLE)
38
39 struct ramtop_table {
40 uint32_t signature;
41 uint32_t addr;
42 uint16_t checksum;
43 } __packed;
44
45 /* Read and validate ramtop_table structure from CMOS */
ramtop_cmos_read(struct ramtop_table * ramtop)46 static int ramtop_cmos_read(struct ramtop_table *ramtop)
47 {
48 u8 i, *p;
49 u16 csum;
50
51 for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++)
52 *p = cmos_read((CMOS_VSTART_ramtop / 8) + i);
53
54 /* Verify signature */
55 if (ramtop->signature != RAMTOP_SIGNATURE) {
56 printk(BIOS_DEBUG, "ramtop_table invalid signature\n");
57 return -1;
58 }
59
60 /* Verify checksum over signature and counter only */
61 csum = ipchksum(ramtop, offsetof(struct ramtop_table, checksum));
62
63 if (csum != ramtop->checksum) {
64 printk(BIOS_DEBUG, "ramtop_table checksum mismatch\n");
65 return -1;
66 }
67
68 return 0;
69 }
70
71 /* Write ramtop_table structure to CMOS */
ramtop_cmos_write(struct ramtop_table * ramtop)72 static void ramtop_cmos_write(struct ramtop_table *ramtop)
73 {
74 u8 i, *p;
75
76 /* Checksum over signature and counter only */
77 ramtop->checksum = ipchksum(ramtop, offsetof(struct ramtop_table, checksum));
78
79 for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++)
80 cmos_write(*p, (CMOS_VSTART_ramtop / 8) + i);
81 }
82
83 /* Update the RAMTOP if required based on the input top_of_ram address */
update_ramtop(uint32_t addr)84 void update_ramtop(uint32_t addr)
85 {
86 struct ramtop_table ramtop;
87
88 /* Read and update ramtop (if required) */
89 if (ramtop_cmos_read(&ramtop) < 0) {
90 /* Structure invalid, re-initialize */
91 ramtop.signature = RAMTOP_SIGNATURE;
92 ramtop.addr = 0;
93 }
94
95 /* Update ramtop if required */
96 if (ramtop.addr == addr)
97 return;
98
99 ramtop.addr = addr;
100
101 /* Write the new top_of_ram address to CMOS */
102 ramtop_cmos_write(&ramtop);
103
104 printk(BIOS_DEBUG, "Updated the RAMTOP address into CMOS 0x%x\n", ramtop.addr);
105 }
106
get_ramtop_addr(void)107 uint32_t get_ramtop_addr(void)
108 {
109 struct ramtop_table ramtop;
110
111 if (ramtop_cmos_read(&ramtop) < 0)
112 return 0;
113
114 return ramtop.addr;
115 }
116
117 /* Early caching of top_of_ram region */
early_ramtop_enable_cache_range(void)118 void early_ramtop_enable_cache_range(void)
119 {
120 uint32_t ramtop = get_ramtop_addr();
121 if (!ramtop)
122 return;
123
124 int mtrr = get_free_var_mtrr();
125 if (mtrr == -1) {
126 printk(BIOS_WARNING, "ramtop_table update failure due to no free MTRR available!\n");
127 return;
128 }
129
130 /*
131 * Background: Some SoCs have a critical bug inside the NEM logic which is responsible
132 * for mapping cached memory to physical memory during tear down and
133 * eventually malfunctions if the number of cache sets is not a power of two.
134 * This can lead to runtime hangs.
135 *
136 * Workaround: To mitigate this issue on affected SoCs, we force the MTRR type to
137 * WC (Write Combining) unless the cache set count is a power of two.
138 * This change alters caching behavior but prevents the runtime failures.
139 */
140 unsigned int mtrr_type = MTRR_TYPE_WRCOMB;
141 /*
142 * We need to make sure late romstage (including FSP-M post mem) will be run
143 * cached. Caching 16MB below ramtop is a safe to cover late romstage.
144 */
145 if (is_cache_sets_power_of_two())
146 mtrr_type = MTRR_TYPE_WRBACK;
147
148 set_var_mtrr(mtrr, ramtop - 16 * MiB, 16 * MiB, mtrr_type);
149 }
150