blob: 5a08c25a62faf384b42780d14c2adfe58d541ca1 [file] [log] [blame]
Francois Toguocea4f922021-04-16 21:20:39 -07001/* SPDX-License-Identifier: GPL-2.0-only */
2
Francois Toguocea4f922021-04-16 21:20:39 -07003#include <arch/bert_storage.h>
Elyes Haouas17a98492022-12-18 09:28:31 +01004#include <console/console.h>
5#include <device/pci_ops.h>
6#include <intelblocks/crashlog.h>
7#include <intelblocks/pmc_ipc.h>
8#include <soc/crashlog.h>
Francois Toguocea4f922021-04-16 21:20:39 -07009#include <soc/iomap.h>
10#include <soc/pci_devs.h>
Elyes Haouas17a98492022-12-18 09:28:31 +010011#include <string.h>
Francois Toguocea4f922021-04-16 21:20:39 -070012
13/* global crashLog info */
14static bool m_pmc_crashLog_support;
15static bool m_pmc_crashLog_present;
16static bool m_cpu_crashLog_support;
17static bool m_cpu_crashLog_present;
18static u32 m_pmc_crashLog_size;
19static u32 m_cpu_crashLog_size;
20static u32 cpu_crash_version;
21static pmc_ipc_discovery_buf_t discovery_buf;
22static pmc_crashlog_desc_table_t descriptor_table;
23static tel_crashlog_devsc_cap_t cpu_cl_devsc_cap;
24static cpu_crashlog_discovery_table_t cpu_cl_disc_tab;
25
26u32 __weak cl_get_cpu_mb_int_addr(void)
27{
28 return CRASHLOG_MAILBOX_INTF_ADDRESS;
29}
30
Subrata Banik603dd562023-03-28 17:54:27 +053031/* Get the SRAM BAR. */
32static uintptr_t sram_get_bar(void)
33{
34 uintptr_t sram_bar;
35 const struct device *dev;
36 struct resource *res;
37
38 dev = pcidev_path_on_root(PCH_DEVFN_SRAM);
39 if (!dev) {
40 printk(BIOS_ERR, "PCH_DEVFN_SRAM device not found!\n");
41 return 0;
42 }
43
44 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
45 if (!res) {
46 printk(BIOS_ERR, "PCH SRAM device not found!\n");
47 return 0;
48 }
49
50 /* Get the base address of the resource */
51 sram_bar = res->base;
52
53 return sram_bar;
54}
55
Francois Toguocea4f922021-04-16 21:20:39 -070056bool pmc_cl_discovery(void)
57{
58 u32 tmp_bar_addr = 0, desc_table_addr = 0;
59
John Zhao270e2552021-07-06 10:28:18 -070060 const struct pmc_ipc_buffer req = { 0 };
61 struct pmc_ipc_buffer res;
Francois Toguocea4f922021-04-16 21:20:39 -070062 uint32_t cmd_reg;
63 int r;
64
65 cmd_reg = pmc_make_ipc_cmd(PMC_IPC_CMD_CRASHLOG,
66 PMC_IPC_CMD_ID_CRASHLOG_DISCOVERY,
67 PMC_IPC_CMD_SIZE_SHIFT);
68 printk(BIOS_DEBUG, "cmd_reg from pmc_make_ipc_cmd %d\n", cmd_reg);
69
John Zhao270e2552021-07-06 10:28:18 -070070 r = pmc_send_ipc_cmd(cmd_reg, &req, &res);
Francois Toguocea4f922021-04-16 21:20:39 -070071
72 if (r < 0) {
73 printk(BIOS_ERR, "pmc_send_ipc_cmd failed in %s\n", __func__);
74 return false;
75 }
John Zhao270e2552021-07-06 10:28:18 -070076 discovery_buf.val_64_bits = ((u64)res.buf[1] << 32) | res.buf[0];
Francois Toguocea4f922021-04-16 21:20:39 -070077
78
79 if (discovery_buf.bits.supported != 1) {
80 printk(BIOS_INFO, "PCH crashlog feature not supported.\n");
81 m_pmc_crashLog_support = false;
82 return false;
83 }
84 m_pmc_crashLog_support = true;
85
Subrata Banik603dd562023-03-28 17:54:27 +053086 tmp_bar_addr = sram_get_bar();
87 if (tmp_bar_addr == 0) {
88 printk(BIOS_ERR, "PCH SRAM not available, crashlog feature can't be enabled.\n");
89 return false;
90 }
Francois Toguocea4f922021-04-16 21:20:39 -070091
92 if (discovery_buf.bits.discov_mechanism == 1) {
93 /* discovery mode */
94 if (discovery_buf.bits.base_offset & BIT(31)) {
95 printk(BIOS_DEBUG, "PCH discovery to be used is disabled.\n");
96 m_pmc_crashLog_present = false;
97 m_pmc_crashLog_size = 0;
98 return false;
99 }
100 desc_table_addr = tmp_bar_addr + discovery_buf.bits.desc_tabl_offset;
101 m_pmc_crashLog_size = pmc_cl_gen_descriptor_table(desc_table_addr,
102 &descriptor_table);
103 printk(BIOS_DEBUG, "PMC CrashLog size in discovery mode: 0x%X\n",
104 m_pmc_crashLog_size);
105 } else {
106 /* legacy mode */
107 if (discovery_buf.bits.dis) {
108 printk(BIOS_DEBUG, "PCH crashlog is disabled in legacy mode.\n");
109 m_pmc_crashLog_present = false;
110 return false;
111 }
112 m_pmc_crashLog_size = (discovery_buf.bits.size != 0) ?
113 (discovery_buf.bits.size * sizeof(u32)) : 0xC00;
114 printk(BIOS_DEBUG, "PMC crashlog size in legacy mode = 0x%x\n",
115 m_pmc_crashLog_size);
116 }
117 m_pmc_crashLog_present = true;
118
119 return true;
120}
121
122u32 cl_get_cpu_bar_addr(void)
123{
124 u32 base_addr = 0;
125 if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR0) {
126 base_addr = pci_read_config32(SA_DEV_TMT, PCI_BASE_ADDRESS_0) &
127 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
128 } else if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR1) {
129 base_addr = pci_read_config32(SA_DEV_TMT, PCI_BASE_ADDRESS_1) &
130 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
131 } else {
132 printk(BIOS_ERR, "Invalid TEL_CFG_BAR value %d, discovery failure expected.\n",
133 cpu_cl_devsc_cap.discovery_data.fields.t_bir_q);
134 }
135
136 return base_addr;
137}
138
139
140u32 cl_get_cpu_tmp_bar(void)
141{
Subrata Banik603dd562023-03-28 17:54:27 +0530142 return sram_get_bar();
Francois Toguocea4f922021-04-16 21:20:39 -0700143}
144
145bool cl_pmc_sram_has_mmio_access(void)
146{
147 if (pci_read_config16(PCH_DEV_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
148 printk(BIOS_ERR, "PMC SSRAM PCI device disabled. Can be enabled in device tree.\n");
149 return false;
150 }
151
152 return true;
153}
154
155static bool cpu_cl_get_capability(tel_crashlog_devsc_cap_t *cl_devsc_cap)
156{
157 cl_devsc_cap->cap_data.data = pci_read_config32(SA_DEV_TMT,
158 TEL_DVSEC_OFFSET + TEL_DVSEC_PCIE_CAP_ID);
159 if (cl_devsc_cap->cap_data.fields.pcie_cap_id != TELEMETRY_EXTENDED_CAP_ID) {
160 printk(BIOS_DEBUG, "Read ID for Telemetry: 0x%x differs from expected: 0x%x\n",
161 cl_devsc_cap->cap_data.fields.pcie_cap_id, TELEMETRY_EXTENDED_CAP_ID);
162 return false;
163 }
164
165 /* walk through the entries until crashLog entry */
166 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(SA_DEV_TMT, TEL_DVSEV_ID);
167 int new_offset = 0;
168 while (cl_devsc_cap->devsc_data.fields.devsc_id != CRASHLOG_DVSEC_ID) {
169 if (cl_devsc_cap->cap_data.fields.next_cap_offset == 0
170 || cl_devsc_cap->cap_data.fields.next_cap_offset == 0xFFFF) {
171 printk(BIOS_DEBUG, "Read invalid pcie_cap_id value: 0x%x\n",
172 cl_devsc_cap->cap_data.fields.pcie_cap_id);
173 return false;
174 }
175 new_offset = cl_devsc_cap->cap_data.fields.next_cap_offset;
176 cl_devsc_cap->cap_data.data = pci_read_config32(SA_DEV_TMT,
177 new_offset + TEL_DVSEC_PCIE_CAP_ID);
178 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(SA_DEV_TMT,
179 new_offset + TEL_DVSEV_ID);
180 }
181 cpu_crash_version = cl_devsc_cap->devsc_data.fields.devsc_ver;
182
183 cl_devsc_cap->discovery_data.data = pci_read_config32(SA_DEV_TMT, new_offset
184 + TEL_DVSEV_DISCOVERY_TABLE_OFFSET);
185
186 return true;
187}
188
189
190static bool cpu_cl_gen_discovery_table(void)
191{
192 u32 bar_addr = 0, disc_tab_addr = 0;
193 bar_addr = cl_get_cpu_bar_addr();
194 disc_tab_addr = bar_addr +
195 cpu_cl_devsc_cap.discovery_data.fields.discovery_table_offset;
196 memset(&cpu_cl_disc_tab, 0, sizeof(cpu_crashlog_discovery_table_t));
197
198 printk(BIOS_DEBUG, "cpu discovery table offset: 0x%x\n",
199 cpu_cl_devsc_cap.discovery_data.fields.discovery_table_offset);
200
201 cpu_cl_disc_tab.header.data = ((u64)read32((u32 *)disc_tab_addr) +
202 ((u64)read32((u32 *)(disc_tab_addr + 4)) << 32));
203
204 cpu_cl_disc_tab.cmd_mailbox.data = read32((u32 *)(disc_tab_addr + 8));
205 cpu_cl_disc_tab.mailbox_data = read32((u32 *)(disc_tab_addr + 12));
206
207 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer count: 0x%x\n",
208 cpu_cl_disc_tab.header.fields.count);
209
210 int cur_offset = 0;
211 for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) {
212 cur_offset = 16 + 8*i;
213 cpu_cl_disc_tab.buffers[i].data = ((u64)read32((u32 *)(disc_tab_addr +
214 cur_offset)) + ((u64)read32((u32 *)
215 (disc_tab_addr + cur_offset + 4)) << 32));
216 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: "
217 "0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size,
218 cpu_cl_disc_tab.buffers[i].fields.offset);
219 m_cpu_crashLog_size += cpu_cl_disc_tab.buffers[i].fields.size * sizeof(u32);
220 }
221
222 m_cpu_crashLog_present = m_cpu_crashLog_size > 0;
223
224 return true;
225}
226
227bool cpu_cl_discovery(void)
228{
229 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
230
231 if (!cpu_cl_get_capability(&cpu_cl_devsc_cap)) {
232 printk(BIOS_ERR, "CPU crashlog capability not found.\n");
233 m_cpu_crashLog_support = false;
234 return false;
235 }
236
237 m_cpu_crashLog_support = true;
238
Kane Chen3c011232021-11-16 09:07:16 +0800239 const struct resource *res = find_resource(SA_DEV_TMT, PCI_BASE_ADDRESS_0);
240 printk(BIOS_DEBUG, "cpu crashlog bar addr: 0x%llX\n", res->base);
Francois Toguocea4f922021-04-16 21:20:39 -0700241
242 if (!cpu_cl_gen_discovery_table()) {
243 printk(BIOS_ERR, "CPU crashlog discovery table not valid.\n");
244 m_cpu_crashLog_present = false;
245 return false;
246 }
Francois Toguocea4f922021-04-16 21:20:39 -0700247
248 return true;
249}
250
251void reset_discovery_buffers(void)
252{
253 memset(&discovery_buf, 0, sizeof(pmc_ipc_discovery_buf_t));
254 memset(&descriptor_table, 0, sizeof(pmc_crashlog_desc_table_t));
255 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
256}
257
258int cl_get_total_data_size(void)
259{
260 return m_pmc_crashLog_size + m_cpu_crashLog_size;
261}
262
263pmc_ipc_discovery_buf_t cl_get_pmc_discovery_buf(void)
264{
265 return discovery_buf;
266}
267
268pmc_crashlog_desc_table_t cl_get_pmc_descriptor_table(void)
269{
270 return descriptor_table;
271}
272
273int cl_get_pmc_record_size(void)
274{
275 return m_pmc_crashLog_size;
276}
277
278int cl_get_cpu_record_size(void)
279{
280 return m_cpu_crashLog_size;
281}
282
283bool cl_cpu_data_present(void)
284{
285 return m_cpu_crashLog_present;
286}
287
288bool cl_pmc_data_present(void)
289{
290 return m_pmc_crashLog_present;
291}
292
293bool cpu_crashlog_support(void)
294{
295 return m_cpu_crashLog_support;
296}
297
298bool pmc_crashlog_support(void)
299{
300 return m_pmc_crashLog_support;
301}
302
303void update_new_pmc_crashlog_size(u32 *pmc_crash_size)
304{
305 m_pmc_crashLog_size = *pmc_crash_size;
306}
307
308cpu_crashlog_discovery_table_t cl_get_cpu_discovery_table(void)
309{
310 return cpu_cl_disc_tab;
311}
312
313void update_new_cpu_crashlog_size(u32 *cpu_crash_size)
314{
315 m_cpu_crashLog_size = *cpu_crash_size;
316}