blob: 89e84d98914cd20c2086a2331b5864331069a412 [file] [log] [blame]
Subrata Banik30a01142023-03-22 00:35:42 +05301/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <console/console.h>
4#include <cpu/x86/mtrr.h>
5#include <ip_checksum.h>
6#include <intelbasecode/ramtop.h>
7#include <pc80/mc146818rtc.h>
8#include <stdint.h>
9
10/* We need a region in CMOS to store the RAMTOP address */
11
12#define RAMTOP_SIGNATURE 0x52544F50 /* 'RTOP' */
13
14#define RAMTOP_CMOS_OFFSET 0x64
15
16/*
17 * Address of the ramtop_cmos_offset byte in CMOS. Should be reserved
18 * in mainboards' cmos.layout and not covered by checksum.
19 */
20
21#if CONFIG(USE_OPTION_TABLE)
22#include "option_table.h"
23#if CMOS_VSTART_ramtop_cmos_offset != RAMTOP_CMOS_OFFSET * 8
24#error "CMOS start for RAMTOP_CMOS is not correct, check your cmos.layout"
25#endif
26#if CMOS_VLEN_ramtop_cmos_offset != 12
27#error "CMOS length for RAMTOP_CMOS bytes are not correct, check your cmos.layout"
28#endif
29#endif
30
31struct ramtop_table {
32 uint32_t signature;
33 uint32_t addr;
34 uint16_t checksum;
35} __packed;
36
37/* Read and validate ramtop_table structure from CMOS */
38static int ramtop_cmos_read(struct ramtop_table *ramtop)
39{
40 u8 i, *p;
41 u16 csum;
42
43 for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++)
44 *p = cmos_read(RAMTOP_CMOS_OFFSET + i);
45
46 /* Verify signature */
47 if (ramtop->signature != RAMTOP_SIGNATURE) {
48 printk(BIOS_DEBUG, "ramtop_table invalid signature\n");
49 return -1;
50 }
51
52 /* Verify checksum over signature and counter only */
53 csum = compute_ip_checksum(ramtop, offsetof(struct ramtop_table, checksum));
54
55 if (csum != ramtop->checksum) {
56 printk(BIOS_DEBUG, "ramtop_table checksum mismatch\n");
57 return -1;
58 }
59
60 return 0;
61}
62
63/* Write ramtop_table structure to CMOS */
64static void ramtop_cmos_write(struct ramtop_table *ramtop)
65{
66 u8 i, *p;
67
68 /* Checksum over signature and counter only */
69 ramtop->checksum = compute_ip_checksum(
70 ramtop, offsetof(struct ramtop_table, checksum));
71
72 for (p = (u8 *)ramtop, i = 0; i < sizeof(*ramtop); i++, p++)
73 cmos_write(*p, RAMTOP_CMOS_OFFSET + i);
74}
75
76/* Update the RAMTOP if required based on the input top_of_ram address */
77void update_ramtop(uint32_t addr)
78{
79 struct ramtop_table ramtop;
80
81 /* Read and update ramtop (if required) */
82 if (ramtop_cmos_read(&ramtop) < 0) {
83 /* Structure invalid, re-initialize */
84 ramtop.signature = RAMTOP_SIGNATURE;
85 ramtop.addr = 0;
86 }
87
88 /* Update ramtop if required */
89 if (ramtop.addr == addr)
90 return;
91
92 ramtop.addr = addr;
93
94 /* Write the new top_of_ram address to CMOS */
95 ramtop_cmos_write(&ramtop);
96
97 printk(BIOS_DEBUG, "Updated the RAMTOP address into CMOS 0x%x\n", ramtop.addr);
98}
99
100static uint32_t get_ramtop_addr(void)
101{
102 struct ramtop_table ramtop;
103
104 if (ramtop_cmos_read(&ramtop) < 0)
105 return 0;
106
107 return ramtop.addr;
108}
109
110/* Early caching of top_of_ram region */
111void early_ramtop_enable_cache_range(void)
112{
113 uint32_t ramtop = get_ramtop_addr();
114 if (!ramtop)
115 return;
116
117 int mtrr = get_free_var_mtrr();
118 if (mtrr == -1) {
119 printk(BIOS_WARNING, "ramtop_table update failure due to no free MTRR available!\n");
120 return;
121 }
122 /*
123 * We need to make sure late romstage (including FSP-M post mem) will be run
124 * cached. Caching 16MB below ramtop is a safe to cover late romstage.
125 */
126 set_var_mtrr(mtrr, ramtop - 16 * MiB, 16 * MiB, MTRR_TYPE_WRBACK);
127}