xref: /aosp_15_r20/external/coreboot/src/drivers/ipmi/ocp/ipmi_sel.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <console/console.h>
4 #include <drivers/ipmi/ipmi_if.h>
5 
6 #include "ipmi_ocp.h"
7 
ipmi_add_sel_entry(int port,unsigned char * data,int size)8 static int ipmi_add_sel_entry(int port, unsigned char *data, int size)
9 {
10 	return ipmi_message(port, IPMI_NETFN_STORAGE, 0, IPMI_ADD_SEL_ENTRY, data, size,
11 				    NULL, 0);
12 }
13 
ipmi_send_to_bmc(unsigned char * data,size_t size)14 void ipmi_send_to_bmc(unsigned char *data, size_t size)
15 {
16 	if (CONFIG(IPMI_KCS)) {
17 		_Static_assert(CONFIG_BMC_KCS_BASE != 0,
18 			"\tBMC_ERROR: Unable to send record: Port #:0\n");
19 
20 		ipmi_add_sel_entry(CONFIG_BMC_KCS_BASE, data, size);
21 	}
22 }
23 
ipmi_send_sel_iio_err(uint8_t iio_stack_num,uint8_t err_id)24 void ipmi_send_sel_iio_err(uint8_t iio_stack_num, uint8_t err_id)
25 {
26 	struct ipmi_sel_iio_err ubslp = {
27 		.record_id = SEL_RECORD_ID,
28 		.record_type = CONFIG_RAS_SEL_VENDOR_ID,
29 		.general_info = SEL_PCIE_IIO_ERR,
30 		.iio_stack_num = iio_stack_num,
31 		.iio_err_id = err_id,
32 	};
33 
34 	ipmi_send_to_bmc((unsigned char *)&ubslp, sizeof(ubslp));
35 	printk(BIOS_DEBUG, "\tsending PCIE IIO device error record to BMC\n");
36 	printk(BIOS_DEBUG, "\tstack # = %x\n", ubslp.iio_stack_num);
37 }
38 
ipmi_send_sel_pcie_dev_err(pci_devfn_t bdf,uint16_t prmry_cnt,uint8_t sec_id,uint8_t prmry_id)39 void ipmi_send_sel_pcie_dev_err(pci_devfn_t bdf, uint16_t prmry_cnt, uint8_t sec_id,
40 				uint8_t prmry_id)
41 {
42 	struct pci_dev_fn *inbdf = (struct pci_dev_fn *)&bdf;
43 	struct ipmi_sel_pcie_dev_err ubslp = {
44 		.record_id = SEL_RECORD_ID,
45 		.record_type = CONFIG_RAS_SEL_VENDOR_ID,
46 		.general_info = SEL_PCIE_DEV_ERR,
47 		.timestamp = 0, /* BMC will apply timestamp */
48 		.aux_loc = 0,
49 		.bdf.bus = inbdf->bus,
50 		.bdf.dev = inbdf->dev,
51 		.bdf.func = inbdf->func >> 12,
52 		.primary_err_count = prmry_cnt,
53 		.primary_id = prmry_id,
54 		.secondary_id = sec_id,
55 	};
56 
57 	ipmi_send_to_bmc((unsigned char *)&ubslp, sizeof(ubslp));
58 	printk(BIOS_DEBUG, "\tsending PCIE device error record to BMC\n");
59 	printk(BIOS_DEBUG, "\tbdf = %x:%x:%x\n", ubslp.bdf.bus, ubslp.bdf.dev, ubslp.bdf.func);
60 	printk(BIOS_DEBUG, "\tubslp.primary_id = %x\n", ubslp.primary_id);
61 	printk(BIOS_DEBUG, "\tsecondary_id = %x\n", ubslp.secondary_id);
62 }
63 
ipmi_send_sel_pcie_dev_fail(uint16_t sts_reg,uint16_t src_id,enum fail_type code)64 void ipmi_send_sel_pcie_dev_fail(uint16_t sts_reg, uint16_t src_id, enum fail_type code)
65 {
66 	struct ipmi_sel_pcie_dev_fail ubslp = {
67 		.record_id = SEL_RECORD_ID,
68 		.record_type = CONFIG_RAS_SEL_VENDOR_ID,
69 		.general_info = SEL_PCIE_DEV_FAIL_ID,
70 		.timestamp = 0, /* BMC will apply timestamp */
71 		.type = code,
72 		.failure_details1 = sts_reg,
73 		.failure_details2 = src_id,
74 	};
75 
76 	ipmi_send_to_bmc((unsigned char *)&ubslp, sizeof(ubslp));
77 	printk(BIOS_DEBUG, "\tsending PCI device FAILURE record to BMC\n");
78 	printk(BIOS_DEBUG, "\terror_code = %x, src_id = %x\n", ubslp.type,
79 	       ubslp.failure_details2);
80 }
81 
ipmi_get_board_config(const int port,struct ipmi_config_rsp * config)82 enum cb_err ipmi_get_board_config(const int port, struct ipmi_config_rsp *config)
83 {
84 	int ret;
85 	struct ipmi_oem_rsp {
86 		struct ipmi_rsp resp;
87 		struct ipmi_config_rsp data;
88 	} __packed;
89 
90 	struct ipmi_oem_rsp rsp;
91 
92 	ret = ipmi_message(port, IPMI_NETFN_OEM, 0x0, IPMI_OEM_GET_BOARD_ID, NULL, 0,
93 			   (unsigned char *)&rsp, sizeof(rsp));
94 	if (ret < sizeof(struct ipmi_rsp) || rsp.resp.completion_code) {
95 		printk(BIOS_ERR, "IPMI: %s command failed (ret=%d resp=0x%x)\n",
96 			__func__, ret, rsp.resp.completion_code);
97 		return CB_ERR;
98 	}
99 	*config = rsp.data;
100 	return CB_SUCCESS;
101 }
102 
get_blade_id(void)103 __weak uint8_t get_blade_id(void)
104 {
105 	struct ipmi_config_rsp rsp = {.slot_id = UINT8_MAX};
106 
107 	if (CONFIG(IPMI_KCS) && CONFIG_BMC_KCS_BASE != 0) {
108 		if (ipmi_get_board_config(CONFIG_BMC_KCS_BASE, &rsp) != CB_SUCCESS)
109 			return UINT8_MAX;
110 	}
111 	return rsp.slot_id;
112 }
113