ec/google/chromeec: Define ACPI_NOTIFY_CROS_EC_MKBP constant
[coreboot.git] / src / soc / intel / pantherlake / crashlog.c
blobd94f4c547665bcd058911ee90851396da908cf2d
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_NODES_COUNT 0x2
18 #define CRASHLOG_PUNIT_STORAGE_OFF_MASK BIT(24)
19 #define CRASHLOG_RE_ARM_STATUS_MASK BIT(25)
20 #define CRASHLOG_CONSUMED_MASK BIT(31)
22 /* Global crashLog info */
23 static bool m_pmc_crash_log_support;
24 static bool m_pmc_crash_log_present;
25 static bool m_cpu_crash_log_support;
26 static bool m_cpu_crash_log_present;
27 static u32 m_pmc_crash_log_size;
28 static u32 m_cpu_crash_log_size;
29 static u32 cpu_crash_version;
30 static pmc_ipc_discovery_buf_t discovery_buf;
31 static pmc_crashlog_desc_table_t descriptor_table;
32 static tel_crashlog_devsc_cap_t cpu_cl_devsc_cap;
33 static cpu_crashlog_discovery_table_t cpu_cl_disc_tab;
34 static uintptr_t disc_tab_addr;
36 static u64 get_disc_tab_header(void)
38 return read64p(disc_tab_addr);
41 /* Get the SRAM BAR. */
42 static uintptr_t get_sram_bar(pci_devfn_t sram_devfn)
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 /* Return the base address of the resource */
60 return res->base;
63 static void configure_sram(const struct device *sram_dev, uintptr_t base_addr)
65 pci_update_config16(sram_dev, PCI_COMMAND, ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY), 0);
67 /* Program BAR 0 and enable command register memory space decoding */
68 pci_write_config32(sram_dev, PCI_BASE_ADDRESS_0, base_addr);
69 pci_or_config16(sram_dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
72 void cl_get_pmc_sram_data(cl_node_t *head)
74 uintptr_t pmc_sram_base = cl_get_cpu_tmp_bar();
75 u32 pmc_crashLog_size = cl_get_pmc_record_size();
76 cl_node_t *cl_cur = head;
78 if (!pmc_crashLog_size) {
79 printk(BIOS_ERR, "No PMC crashlog records\n");
80 return;
83 if (!pmc_sram_base) {
84 printk(BIOS_ERR, "PMC SRAM base not valid\n");
85 return;
88 if (!cl_pmc_sram_has_mmio_access())
89 return;
91 printk(BIOS_DEBUG, "PMC crashLog size : 0x%x\n", pmc_crashLog_size);
93 /* Goto tail node */
94 while (cl_cur && cl_cur->next) {
95 cl_cur = cl_cur->next;
98 /* Process crashlog records */
99 for (int i = 0; i < descriptor_table.numb_regions + 1; i++) {
100 uintptr_t sram_base = 0;
101 bool pmc_sram = true;
102 printk(BIOS_DEBUG, "Region[0x%x].Tag=0x%x offset=0x%x, size=0x%x\n",
104 descriptor_table.regions[i].bits.assign_tag,
105 descriptor_table.regions[i].bits.offset,
106 descriptor_table.regions[i].bits.size);
108 if (!descriptor_table.regions[i].bits.size)
109 continue;
112 * Region with metadata TAG contains information about BDF entry for SOC PMC SRAM
113 * and IOE SRAM. We don't need to parse this as we already define BDFs in
114 * soc/pci_devs.h for these SRAMs. Also we need to skip this region as it does not
115 * contain any crashlog data.
117 if (descriptor_table.regions[i].bits.assign_tag ==
118 CRASHLOG_DESCRIPTOR_TABLE_TAG_META) {
119 pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
120 sizeof(u32);
121 printk(BIOS_DEBUG, "Found metadata tag. PMC crashlog size adjusted to: 0x%x\n",
122 pmc_crashLog_size);
123 continue;
124 } else {
125 if (descriptor_table.regions[i].bits.assign_tag ==
126 CRASHLOG_DESCRIPTOR_TABLE_TAG_SOC)
127 sram_base = pmc_sram_base;
128 else
129 continue;
131 cl_node_t *cl_node = malloc_cl_node(descriptor_table.regions[i].bits.size);
133 if (!cl_node) {
134 printk(BIOS_DEBUG, "failed to allocate cl_node [region = %d]\n", i);
135 goto pmc_send_re_arm_after_reset;
138 if (cl_copy_data_from_sram(sram_base,
139 descriptor_table.regions[i].bits.offset,
140 descriptor_table.regions[i].bits.size,
141 cl_node->data,
143 pmc_sram)) {
144 cl_cur->next = cl_node;
145 cl_cur = cl_cur->next;
146 } else {
147 /* Coping data from sram failed */
148 pmc_crashLog_size -= descriptor_table.regions[i].bits.size *
149 sizeof(u32);
150 printk(BIOS_DEBUG, "PMC crashlog size adjusted to: 0x%x\n",
151 pmc_crashLog_size);
152 /* Free cl_node */
153 free_cl_node(cl_node);
158 update_new_pmc_crashlog_size(&pmc_crashLog_size);
160 pmc_send_re_arm_after_reset:
161 /* When bit 7 of discov cmd resp is set -> bit 2 of size field */
162 cl_pmc_re_arm_after_reset();
164 /* Clear the SSRAM region after copying the error log */
165 cl_pmc_clear();
168 bool pmc_cl_discovery(void)
170 uintptr_t bar_addr = 0, desc_table_addr = 0;
172 const struct pmc_ipc_buffer req = { 0 };
173 struct pmc_ipc_buffer res;
174 uint32_t cmd_reg;
175 int r;
177 cmd_reg = pmc_make_ipc_cmd(PMC_IPC_CMD_CRASHLOG,
178 PMC_IPC_CMD_ID_CRASHLOG_DISCOVERY,
179 PMC_IPC_CMD_SIZE_SHIFT);
180 printk(BIOS_DEBUG, "cmd_reg from pmc_make_ipc_cmd %d in %s\n", cmd_reg, __func__);
182 r = pmc_send_ipc_cmd(cmd_reg, &req, &res);
184 if (r < 0) {
185 printk(BIOS_ERR, "pmc_send_ipc_cmd failed in %s\n", __func__);
186 return false;
188 discovery_buf.conv_val_64_bits = ((u64)res.buf[1] << 32) | res.buf[0];
190 if ((discovery_buf.conv_bits64.supported != 1) ||
191 (discovery_buf.conv_bits64.discov_mechanism == 0) ||
192 (discovery_buf.conv_bits64.crash_dis_sts == 1)) {
193 printk(BIOS_INFO, "PCH crashlog feature not supported.\n");
194 m_pmc_crash_log_support = false;
195 m_pmc_crash_log_size = 0;
196 printk(BIOS_DEBUG, "discovery_buf supported: %d, mechanism: %d, CrashDisSts: %d\n",
197 discovery_buf.conv_bits64.supported,
198 discovery_buf.conv_bits64.discov_mechanism,
199 discovery_buf.conv_bits64.crash_dis_sts);
200 return false;
203 printk(BIOS_INFO, "PMC crashlog feature is supported.\n");
204 m_pmc_crash_log_support = true;
206 /* Program BAR 0 and enable command register memory space decoding */
207 bar_addr = get_sram_bar(PCI_DEVFN_SRAM);
208 if (bar_addr == 0) {
209 printk(BIOS_ERR, "PCH SRAM not available, crashlog feature can't be enabled.\n");
210 return false;
213 configure_sram(PCI_DEV_SRAM, bar_addr);
215 desc_table_addr = bar_addr + discovery_buf.conv_bits64.desc_tabl_offset;
216 m_pmc_crash_log_size = pmc_cl_gen_descriptor_table(desc_table_addr,
217 &descriptor_table);
218 printk(BIOS_DEBUG, "PMC CrashLog size in discovery mode: 0x%X\n",
219 m_pmc_crash_log_size);
220 m_pmc_crash_log_present = m_pmc_crash_log_size > 0;
222 return true;
225 uintptr_t cl_get_cpu_bar_addr(void)
227 uintptr_t base_addr = 0;
228 if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR0) {
229 base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_0) &
230 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
231 } else if (cpu_cl_devsc_cap.discovery_data.fields.t_bir_q == TEL_DVSEC_TBIR_BAR1) {
232 base_addr = pci_read_config32(PCI_DEV_TELEMETRY, PCI_BASE_ADDRESS_1) &
233 ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
234 } else {
235 printk(BIOS_ERR, "Invalid TEL_CFG_BAR value %d, discovery failure expected.\n",
236 cpu_cl_devsc_cap.discovery_data.fields.t_bir_q);
239 return base_addr;
242 uintptr_t cl_get_cpu_tmp_bar(void)
244 return get_sram_bar(PCI_DEVFN_SRAM);
247 bool cl_pmc_sram_has_mmio_access(void)
249 if (pci_read_config16(PCI_DEV_SRAM, PCI_VENDOR_ID) == 0xFFFF) {
250 printk(BIOS_ERR, "PMC SSRAM PCI device disabled. Can be enabled in device tree.\n");
251 return false;
254 return true;
257 static bool cpu_cl_get_capability(tel_crashlog_devsc_cap_t *cl_devsc_cap)
259 cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
260 TEL_DVSEC_OFFSET + TEL_DVSEC_PCIE_CAP_ID);
261 if (cl_devsc_cap->cap_data.fields.pcie_cap_id != TELEMETRY_EXTENDED_CAP_ID) {
262 printk(BIOS_DEBUG, "Read ID for Telemetry: 0x%x differs from expected: 0x%x\n",
263 cl_devsc_cap->cap_data.fields.pcie_cap_id, TELEMETRY_EXTENDED_CAP_ID);
264 return false;
267 /* Walk through the entries until crashLog entry */
268 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY, TEL_DVSEV_ID);
269 int new_offset = 0;
270 while (cl_devsc_cap->devsc_data.fields.devsc_id != CRASHLOG_DVSEC_ID) {
271 if (cl_devsc_cap->cap_data.fields.next_cap_offset == 0
272 || cl_devsc_cap->cap_data.fields.next_cap_offset == 0xFFFF) {
273 printk(BIOS_DEBUG, "Read invalid pcie_cap_id value: 0x%x\n",
274 cl_devsc_cap->cap_data.fields.pcie_cap_id);
275 return false;
277 new_offset = cl_devsc_cap->cap_data.fields.next_cap_offset;
278 cl_devsc_cap->cap_data.data = pci_read_config32(PCI_DEV_TELEMETRY,
279 new_offset + TEL_DVSEC_PCIE_CAP_ID);
280 cl_devsc_cap->devsc_data.data_32[1] = pci_read_config32(PCI_DEV_TELEMETRY,
281 new_offset + TEL_DVSEV_ID);
283 cpu_crash_version = cl_devsc_cap->devsc_data.fields.devsc_ver;
285 cl_devsc_cap->discovery_data.data = pci_read_config32(PCI_DEV_TELEMETRY, new_offset
286 + TEL_DVSEV_DISCOVERY_TABLE_OFFSET);
288 return true;
291 static u32 get_disc_table_offset(void)
293 u32 offset = cpu_cl_devsc_cap.discovery_data.fields.discovery_table_offset;
295 return offset;
298 static bool is_crashlog_data_valid(u32 dw0)
300 return (dw0 != 0x0 && dw0 != INVALID_CRASHLOG_RECORD);
303 static bool cpu_cl_gen_discovery_table(void)
305 uintptr_t bar_addr = cl_get_cpu_bar_addr();
307 if (!bar_addr)
308 return false;
310 disc_tab_addr = bar_addr + get_disc_table_offset();
311 memset(&cpu_cl_disc_tab, 0, sizeof(cpu_crashlog_discovery_table_t));
312 cpu_cl_disc_tab.header.data = get_disc_tab_header();
313 /* Check both 32 bit header data and status register for non-zero values */
314 if ((!is_crashlog_data_valid(cpu_cl_disc_tab.header.data & 0xFFFFFFFF)) &&
315 (!is_crashlog_data_valid((cpu_cl_disc_tab.header.data) >> 32)))
316 return false;
318 u32 cur_offset = 0;
319 cpu_cl_disc_tab.header.fields.count = CRASHLOG_NODES_COUNT;
320 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer count: 0x%x\n",
321 cpu_cl_disc_tab.header.fields.count);
322 for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) {
323 cur_offset = 8 + 24 * i;
324 u32 cl_buffer_size = read32p(disc_tab_addr + cur_offset + 4);
325 /* Check for buffer size */
326 if (!(is_crashlog_data_valid(cl_buffer_size)))
327 continue;
329 u32 dw0 = read32p(disc_tab_addr + cur_offset);
330 if (dw0 & CRASHLOG_CONSUMED_MASK) {
331 printk(BIOS_DEBUG, "cpu crashlog records already consumed."
332 "id: 0x%x dw0: 0x%x\n", i, dw0);
333 break;
336 cpu_cl_disc_tab.buffers[i].data = read64p(disc_tab_addr + cur_offset);
337 printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: "
338 "0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size,
339 cpu_cl_disc_tab.buffers[i].fields.offset);
340 m_cpu_crash_log_size += cpu_cl_disc_tab.buffers[i].fields.size * sizeof(u32);
343 if (m_cpu_crash_log_size > 0)
344 m_cpu_crash_log_present = true;
345 else
346 m_cpu_crash_log_present = false;
348 return true;
351 bool cpu_cl_discovery(void)
353 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
355 if (!cpu_cl_get_capability(&cpu_cl_devsc_cap)) {
356 printk(BIOS_ERR, "CPU crashlog capability not found.\n");
357 m_cpu_crash_log_support = false;
358 return false;
361 m_cpu_crash_log_support = true;
363 if (!cpu_cl_gen_discovery_table()) {
364 printk(BIOS_ERR, "CPU crashlog discovery table not valid.\n");
365 m_cpu_crash_log_present = false;
366 return false;
369 return true;
372 void reset_discovery_buffers(void)
374 memset(&discovery_buf, 0, sizeof(pmc_ipc_discovery_buf_t));
375 memset(&descriptor_table, 0, sizeof(pmc_crashlog_desc_table_t));
376 memset(&cpu_cl_devsc_cap, 0, sizeof(tel_crashlog_devsc_cap_t));
379 int cl_get_total_data_size(void)
381 printk(BIOS_DEBUG, "crashlog size:pmc-0x%x, cpu-0x%x\n",
382 m_pmc_crash_log_size, m_cpu_crash_log_size);
383 return m_pmc_crash_log_size + m_cpu_crash_log_size;
386 static uintptr_t get_control_status_interface(void)
388 if (disc_tab_addr)
389 return (disc_tab_addr + CONTROL_INTERFACE_OFFSET * sizeof(u32));
390 return 0;
393 int cpu_cl_clear_data(void)
395 return 0;
398 static bool wait_and_check(u32 bit_mask)
400 u32 stall_cnt = 0;
402 do {
403 cpu_cl_disc_tab.header.data = get_disc_tab_header();
404 udelay(CPU_CRASHLOG_WAIT_STALL);
405 stall_cnt++;
406 } while (((cpu_cl_disc_tab.header.data & bit_mask) == 0) &&
407 ((stall_cnt * CPU_CRASHLOG_WAIT_STALL) < CPU_CRASHLOG_WAIT_TIMEOUT));
409 return (cpu_cl_disc_tab.header.data & bit_mask);
412 void cpu_cl_rearm(void)
414 uintptr_t ctrl_sts_intfc_addr = get_control_status_interface();
416 if (!ctrl_sts_intfc_addr) {
417 printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
418 return;
421 /* Rearm the CPU crashlog. Crashlog does not get collected if rearming fails */
422 cl_punit_control_interface_t punit_ctrl_intfc;
423 memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
424 punit_ctrl_intfc.fields.set_re_arm = 1;
425 write32p(ctrl_sts_intfc_addr, punit_ctrl_intfc.data);
427 if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK))
428 printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n");
429 else
430 printk(BIOS_DEBUG, "CPU crashlog re_arm asserted\n");
433 void cpu_cl_cleanup(void)
435 /* Perform any SOC specific cleanup after reading the crashlog data from SRAM */
436 uintptr_t ctrl_sts_intfc_addr = get_control_status_interface();
438 if (!ctrl_sts_intfc_addr) {
439 printk(BIOS_ERR, "CPU crashlog control and status interface address not valid\n");
440 return;
443 /* If storage-off is supported, turn off the PUNIT SRAM
444 * stroage to save power. This clears crashlog records also.
447 if (!cpu_cl_disc_tab.header.fields.storage_off_support) {
448 printk(BIOS_INFO, "CPU crashlog storage_off not supported\n");
449 return;
452 cl_punit_control_interface_t punit_ctrl_intfc;
453 memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
454 punit_ctrl_intfc.fields.set_storage_off = 1;
455 write32p(ctrl_sts_intfc_addr, punit_ctrl_intfc.data);
457 if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK))
458 printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n");
459 else
460 printk(BIOS_DEBUG, "CPU crashlog storage_off asserted\n");
463 pmc_ipc_discovery_buf_t cl_get_pmc_discovery_buf(void)
465 return discovery_buf;
468 pmc_crashlog_desc_table_t cl_get_pmc_descriptor_table(void)
470 return descriptor_table;
473 int cl_get_pmc_record_size(void)
475 return m_pmc_crash_log_size;
478 int cl_get_cpu_record_size(void)
480 return m_cpu_crash_log_size;
483 bool cl_cpu_data_present(void)
485 return m_cpu_crash_log_present;
488 bool cl_pmc_data_present(void)
490 return m_pmc_crash_log_present;
493 bool cpu_crashlog_support(void)
495 return m_cpu_crash_log_support;
498 bool pmc_crashlog_support(void)
500 return m_pmc_crash_log_support;
503 void update_new_pmc_crashlog_size(u32 *pmc_crash_size)
505 m_pmc_crash_log_size = *pmc_crash_size;
508 cpu_crashlog_discovery_table_t cl_get_cpu_discovery_table(void)
510 return cpu_cl_disc_tab;
513 void update_new_cpu_crashlog_size(u32 *cpu_crash_size)
515 m_cpu_crash_log_size = *cpu_crash_size;