soc/intel/xeon_sp/chip_common: Improve the domain ID
[coreboot2.git] / src / soc / intel / meteorlake / crashlog.c
blob52d23714ffa8248a9449472cbbfd97e09cdfdd87
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/bert_storage.h>
4 #include <console/console.h>
5 #include <cpu/cpu.h>
6 #include <cpu/intel/cpu_ids.h>
7 #include <delay.h>
8 #include <device/pci_ops.h>
9 #include <intelblocks/crashlog.h>
10 #include <intelblocks/pmc_ipc.h>
11 #include <soc/crashlog.h>
12 #include <soc/iomap.h>
13 #include <soc/pci_devs.h>
14 #include <string.h>
16 #define CONTROL_INTERFACE_OFFSET 0x5
17 #define CRASHLOG_PUNIT_STORAGE_OFF_MASK BIT(24)
18 #define CRASHLOG_RE_ARM_STATUS_MASK BIT(25)
19 #define CRASHLOG_CONSUMED_MASK BIT(31)
21 /* global crashLog info */
22 static bool m_pmc_crashLog_support;
23 static bool m_pmc_crashLog_present;
24 static bool m_cpu_crashLog_support;
25 static bool m_cpu_crashLog_present;
26 static u32 m_pmc_crashLog_size;
27 static u32 m_cpu_crashLog_size;
28 static u32 cpu_crash_version;
29 static pmc_ipc_discovery_buf_t discovery_buf;
30 static pmc_crashlog_desc_table_t descriptor_table;
31 static tel_crashlog_devsc_cap_t cpu_cl_devsc_cap;
32 static cpu_crashlog_discovery_table_t cpu_cl_disc_tab;
33 static u32 disc_tab_addr;
35 static u64 get_disc_tab_header(void)
37 return read64((void *)disc_tab_addr);
40 /* Get the SRAM BAR. */
41 static uintptr_t get_sram_bar(pci_devfn_t sram_devfn)
43 uintptr_t sram_bar;
44 const struct device *dev;
45 struct resource *res;
47 dev = pcidev_path_on_root(sram_devfn);
48 if (!dev) {
49 printk(BIOS_ERR, "device: 0x%x not found!\n", sram_devfn);
50 return 0;
53 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
54 if (!res) {
55 printk(BIOS_ERR, "SOC SRAM device not found!\n");
56 return 0;
59 /* Get the base address of the resource */
60 sram_bar = res->base;
62 return sram_bar;
65 static void configure_sram(const struct device *sram_dev, u32 base_addr)
67 pci_update_config16(sram_dev, PCI_COMMAND, ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY), 0);
69 /* Program BAR 0 and enable command register memory space decoding */
70 pci_write_config32(sram_dev, PCI_BASE_ADDRESS_0, base_addr);
71 pci_or_config16(sram_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
74 void cl_get_pmc_sram_data(cl_node_t *head)
76 u32 pmc_sram_base = cl_get_cpu_tmp_bar();
77 u32 ioe_sram_base = get_sram_bar(PCI_DEVFN_IOE_SRAM);
78 u32 pmc_crashLog_size = cl_get_pmc_record_size();
79 cl_node_t *cl_cur = head;
81 if (!pmc_crashLog_size) {
82 printk(BIOS_ERR, "No PMC crashlog records\n");
83 return;
86 if (!pmc_sram_base) {
87 printk(BIOS_ERR, "PMC SRAM base not valid\n");
88 return;
91 if (!ioe_sram_base) {
92 printk(BIOS_ERR, "IOE SRAM base not valid\n");
93 return;
96 configure_sram(PCI_DEV_IOE_SRAM, ioe_sram_base);
98 if (!cl_pmc_sram_has_mmio_access())
99 return;
101 if (!cl_ioe_sram_has_mmio_access())
102 return;
104 printk(BIOS_DEBUG, "PMC crashLog size : 0x%x\n", pmc_crashLog_size);
106 /* goto tail node */
107 while (cl_cur && cl_cur->next) {
108 cl_cur = cl_cur->next;
111 /* process crashlog records */
112 for (int i = 0; i < descriptor_table.numb_regions + 1; i++) {
114 u32 sram_base = 0;
115 bool pmc_sram = true;
116 printk(BIOS_DEBUG, "Region[0x%x].Tag=0x%x offset=0x%x, size=0x%x\n",
118 descriptor_table.regions[i].bits.assign_tag,
119 descriptor_table.regions[i].bits.offset,
120 descriptor_table.regions[i].bits.size);
122 if (!descriptor_table.regions[i].bits.size)
123 continue;
126 * Region with metadata TAG contains information about BDF entry for SOC PMC SRAM
127 * and IOE SRAM. We don't need to parse this as we already define BDFs in
128 * soc/pci_devs.h for these SRAMs. Also we need to skip this region as it does not
129 * contain any crashlog data.
131 if (descriptor_table.regions[i].bits.assign_tag ==
132 CRASHLOG_DESCRIPTOR_TABLE_TAG_META) {
133 pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
134 sizeof(u32);
135 printk(BIOS_DEBUG, "Found metadata tag. PMC crashlog size adjusted to: 0x%x\n",
136 pmc_crashLog_size);
137 continue;
138 } else {
139 if (descriptor_table.regions[i].bits.assign_tag ==
140 CRASHLOG_DESCRIPTOR_TABLE_TAG_SOC)
141 sram_base = pmc_sram_base;
142 else if (descriptor_table.regions[i].bits.assign_tag ==
143 CRASHLOG_DESCRIPTOR_TABLE_TAG_IOE)
144 sram_base = ioe_sram_base;
145 else
146 continue;
148 cl_node_t *cl_node = malloc_cl_node(descriptor_table.regions[i].bits.size);
150 if (!cl_node) {
151 printk(BIOS_DEBUG, "failed to allocate cl_node [region = %d]\n", i);
152 goto pmc_send_re_arm_after_reset;
155 if (cl_copy_data_from_sram(sram_base,
156 descriptor_table.regions[i].bits.offset,
157 descriptor_table.regions[i].bits.size,
158 cl_node->data,
160 pmc_sram)) {
161 cl_cur->next = cl_node;
162 cl_cur = cl_cur->next;
163 } else {
164 /* coping data from sram failed */
165 pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
166 sizeof(u32);
167 printk(BIOS_DEBUG, "PMC crashlog size adjusted to: 0x%x\n",
168 pmc_crashLog_size);
169 /* free cl_node */
170 free_cl_node(cl_node);
175 update_new_pmc_crashlog_size(&pmc_crashLog_size);
177 pmc_send_re_arm_after_reset:
178 /* when bit 7 of discov cmd resp is set -> bit 2 of size field */
179 cl_pmc_re_arm_after_reset();
181 /* Clear the SSRAM region after copying the error log */
182 cl_pmc_clear();
185 bool pmc_cl_discovery(void)
187 u32 bar_addr = 0, desc_table_addr = 0;
189 const struct pmc_ipc_buffer req = { 0 };
190 struct pmc_ipc_buffer res;
191 uint32_t cmd_reg;
192 int r;
194 cmd_reg = pmc_make_ipc_cmd(PMC_IPC_CMD_CRASHLOG,
195 PMC_IPC_CMD_ID_CRASHLOG_DISCOVERY,
196 PMC_IPC_CMD_SIZE_SHIFT);
197 printk(BIOS_DEBUG, "cmd_reg from pmc_make_ipc_cmd %d in %s\n", cmd_reg, __func__);
199 r = pmc_send_ipc_cmd(cmd_reg, &req, &res);
201 if (r < 0) {
202 printk(BIOS_ERR, "pmc_send_ipc_cmd failed in %s\n", __func__);
203 return false;
205 discovery_buf.conv_val_64_bits = ((u64)res.buf[1] << 32) | res.buf[0];
207 if ((discovery_buf.conv_bits64.supported != 1) ||
208 (discovery_buf.conv_bits64.discov_mechanism == 0) ||
209 (discovery_buf.conv_bits64.crash_dis_sts == 1)) {
210 printk(BIOS_INFO, "PCH crashlog feature not supported.\n");
211 m_pmc_crashLog_support = false;
212 m_pmc_crashLog_size = 0;
213 printk(BIOS_DEBUG, "discovery_buf supported: %d, mechanism: %d, CrashDisSts: %d\n",
214 discovery_buf.conv_bits64.supported,
215 discovery_buf.conv_bits64.discov_mechanism,
216 discovery_buf.conv_bits64.crash_dis_sts);
217 return false;
220 printk(BIOS_INFO, "PMC crashlog feature is supported.\n");
221 m_pmc_crashLog_support = true;
223 /* Program BAR 0 and enable command register memory space decoding */
224 bar_addr = get_sram_bar(PCI_DEVFN_SRAM);
225 if (bar_addr == 0) {
226 printk(BIOS_ERR, "PCH SRAM not available, crashlog feature can't be enabled.\n");
227 return false;
230 configure_sram(PCI_DEV_SRAM, bar_addr);
232 desc_table_addr = bar_addr + discovery_buf.conv_bits64.desc_tabl_offset;
233 m_pmc_crashLog_size = pmc_cl_gen_descriptor_table(desc_table_addr,
234 &descriptor_table);
235 printk(BIOS_DEBUG, "PMC CrashLog size in discovery mode: 0x%X\n",
236 m_pmc_crashLog_size);
237 m_pmc_crashLog_present = m_pmc_crashLog_size > 0;
239 return true;
242 u32 cl_get_cpu_bar_addr(void)
244 u32 base_addr = 0;
245 if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR0) {
246 base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_0) &
247 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
248 } else if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR1) {
249 base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_1) &
250 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
251 } else {
252 printk(BIOS_ERR, "Invalid TEL_CFG_BAR value %d, discovery failure expected.\n",
253 cpu_cl_devsc_cap.discovery_data.fields.t_bir_q);
256 return base_addr;
259 u32 cl_get_cpu_tmp_bar(void)
261 return get_sram_bar(PCI_DEVFN_SRAM);
264 bool cl_pmc_sram_has_mmio_access(void)
266 if (pci_read_config16(PCI_DEV_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
267 printk(BIOS_ERR, "PMC SSRAM PCI device disabled. Can be enabled in device tree.\n");
268 return false;
271 return true;
274 bool cl_ioe_sram_has_mmio_access(void)
276 if (pci_read_config16(PCI_DEV_IOE_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
277 printk(BIOS_ERR, "IOE SSRAM PCI device disabled. Can be enabled in device tree.\n");
278 return false;
280 return true;
283 static bool cpu_cl_get_capability(tel_crashlog_devsc_cap_t *cl_devsc_cap)
285 cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
286 TEL_DVSEC_OFFSET + TEL_DVSEC_PCIE_CAP_ID);
287 if (cl_devsc_cap->cap_data.fields.pcie_cap_id != TELEMETRY_EXTENDED_CAP_ID) {
288 printk(BIOS_DEBUG, "Read ID for Telemetry: 0x%x differs from expected: 0x%x\n",
289 cl_devsc_cap->cap_data.fields.pcie_cap_id, TELEMETRY_EXTENDED_CAP_ID);
290 return false;
293 /* walk through the entries until crashLog entry */
294 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY, TEL_DVSEV_ID);
295 int new_offset = 0;
296 while (cl_devsc_cap->devsc_data.fields.devsc_id != CRASHLOG_DVSEC_ID) {
297 if (cl_devsc_cap->cap_data.fields.next_cap_offset == 0
298 || cl_devsc_cap->cap_data.fields.next_cap_offset == 0xFFFF) {
299 printk(BIOS_DEBUG, "Read invalid pcie_cap_id value: 0x%x\n",
300 cl_devsc_cap->cap_data.fields.pcie_cap_id);
301 return false;
303 new_offset = cl_devsc_cap->cap_data.fields.next_cap_offset;
304 cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
305 new_offset + TEL_DVSEC_PCIE_CAP_ID);
306 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY,
307 new_offset + TEL_DVSEV_ID);
309 cpu_crash_version = cl_devsc_cap->devsc_data.fields.devsc_ver;
311 cl_devsc_cap->discovery_data.data = pci_read_config32(PCI_DEV_TELEMETRY, new_offset
312 + TEL_DVSEV_DISCOVERY_TABLE_OFFSET);
314 return true;
317 static u32 get_disc_table_offset(void)
319 u32 offset = cpu_cl_devsc_cap.discovery_data.fields.discovery_table_offset;
320 if (cpu_get_cpuid() >= CPUID_METEORLAKE_B0) {
321 offset <<= 3;
322 printk(BIOS_DEBUG, "adjusted cpu discovery table offset: 0x%x\n", offset);
325 return offset;
328 static bool is_crashlog_data_valid(u32 dw0)
330 return (dw0 != 0x0 && dw0 != INVALID_CRASHLOG_RECORD);
333 static bool cpu_cl_gen_discovery_table(void)
335 u32 bar_addr = cl_get_cpu_bar_addr();
337 if (!bar_addr)
338 return false;
340 disc_tab_addr = bar_addr + get_disc_table_offset();
342 u32 dw0 = read32((u32 *)disc_tab_addr);
343 if (!is_crashlog_data_valid(dw0))
344 return false;
346 memset(&cpu_cl_disc_tab, 0, sizeof(cpu_crashlog_discovery_table_t));
347 cpu_cl_disc_tab.header.data = get_disc_tab_header();
348 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer count: 0x%x\n",
349 cpu_cl_disc_tab.header.fields.count);
351 int cur_offset = 0;
352 for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) {
353 cur_offset = 8 + 24 * i;
355 dw0 = read32((u32 *)disc_tab_addr + cur_offset);
356 if (!is_crashlog_data_valid(dw0))
357 continue;
359 if (dw0 & CRASHLOG_CONSUMED_MASK) {
360 printk(BIOS_DEBUG, "cpu crashlog records already consumed."
361 "id: 0x%x dw0: 0x%x\n", i, dw0);
362 break;
365 cpu_cl_disc_tab.buffers[i].data = read64((void *)(disc_tab_addr + cur_offset));
366 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: "
367 "0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size,
368 cpu_cl_disc_tab.buffers[i].fields.offset);
369 m_cpu_crashLog_size += cpu_cl_disc_tab.buffers[i].fields.size * sizeof(u32);
372 if (m_cpu_crashLog_size > 0)
373 m_cpu_crashLog_present = true;
374 else
375 m_cpu_crashLog_present = false;
377 return true;
380 bool cpu_cl_discovery(void)
382 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
384 if (!cpu_cl_get_capability(&cpu_cl_devsc_cap)) {
385 printk(BIOS_ERR, "CPU crashlog capability not found.\n");
386 m_cpu_crashLog_support = false;
387 return false;
390 m_cpu_crashLog_support = true;
392 if (!cpu_cl_gen_discovery_table()) {
393 printk(BIOS_ERR, "CPU crashlog discovery table not valid.\n");
394 m_cpu_crashLog_present = false;
395 return false;
398 return true;
401 void reset_discovery_buffers(void)
403 memset(&discovery_buf, 0, sizeof(pmc_ipc_discovery_buf_t));
404 memset(&descriptor_table, 0, sizeof(pmc_crashlog_desc_table_t));
405 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
408 int cl_get_total_data_size(void)
410 printk(BIOS_DEBUG, "crashlog size:pmc-0x%x, cpu-0x%x\n",
411 m_pmc_crashLog_size, m_cpu_crashLog_size);
412 return m_pmc_crashLog_size + m_cpu_crashLog_size;
415 static u32 get_control_status_interface(void)
417 if (disc_tab_addr)
418 return (disc_tab_addr + CONTROL_INTERFACE_OFFSET * sizeof(u32));
419 return 0;
422 int cpu_cl_clear_data(void)
424 return 0;
427 static bool wait_and_check(u32 bit_mask)
429 u32 stall_cnt = 0;
431 do {
432 cpu_cl_disc_tab.header.data = get_disc_tab_header();
433 udelay(CPU_CRASHLOG_WAIT_STALL);
434 stall_cnt++;
435 } while (((cpu_cl_disc_tab.header.data & bit_mask) == 0) &&
436 ((stall_cnt * CPU_CRASHLOG_WAIT_STALL) < CPU_CRASHLOG_WAIT_TIMEOUT));
438 return (cpu_cl_disc_tab.header.data & bit_mask);
441 void cpu_cl_rearm(void)
443 u32 ctrl_sts_intfc_addr = get_control_status_interface();
445 if (!ctrl_sts_intfc_addr) {
446 printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
447 return;
450 /* Rearm the CPU crashlog. Crashlog does not get collected if rearming fails */
451 cl_punit_control_interface_t punit_ctrl_intfc;
452 memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
453 punit_ctrl_intfc.fields.set_re_arm = 1;
454 write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);
456 if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK))
457 printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n");
458 else
459 printk(BIOS_DEBUG, "CPU crashlog re_arm asserted\n");
462 void cpu_cl_cleanup(void)
464 /* Perform any SOC specific cleanup after reading the crashlog data from SRAM */
465 u32 ctrl_sts_intfc_addr = get_control_status_interface();
467 if (!ctrl_sts_intfc_addr) {
468 printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
469 return;
472 /* If storage-off is supported, turn off the PUNIT SRAM
473 * stroage to save power. This clears crashlog records also.
476 if (!cpu_cl_disc_tab.header.fields.storage_off_support) {
477 printk(BIOS_INFO, "CPU crashlog storage_off not supported\n");
478 return;
481 cl_punit_control_interface_t punit_ctrl_intfc;
482 memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
483 punit_ctrl_intfc.fields.set_storage_off = 1;
484 write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);
486 if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK))
487 printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n");
488 else
489 printk(BIOS_DEBUG, "CPU crashlog storage_off asserted\n");
492 pmc_ipc_discovery_buf_t cl_get_pmc_discovery_buf(void)
494 return discovery_buf;
497 pmc_crashlog_desc_table_t cl_get_pmc_descriptor_table(void)
499 return descriptor_table;
502 int cl_get_pmc_record_size(void)
504 return m_pmc_crashLog_size;
507 int cl_get_cpu_record_size(void)
509 return m_cpu_crashLog_size;
512 bool cl_cpu_data_present(void)
514 return m_cpu_crashLog_present;
517 bool cl_pmc_data_present(void)
519 return m_pmc_crashLog_present;
522 bool cpu_crashlog_support(void)
524 return m_cpu_crashLog_support;
527 bool pmc_crashlog_support(void)
529 return m_pmc_crashLog_support;
532 void update_new_pmc_crashlog_size(u32 *pmc_crash_size)
534 m_pmc_crashLog_size = *pmc_crash_size;
537 cpu_crashlog_discovery_table_t cl_get_cpu_discovery_table(void)
539 return cpu_cl_disc_tab;
542 void update_new_cpu_crashlog_size(u32 *cpu_crash_size)
544 m_cpu_crashLog_size = *cpu_crash_size;