xref: /openbmc/libpldm/src/dsp/bios.c (revision 48761c62)
1*48761c62SAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2*48761c62SAndrew Jeffery #include <libpldm/base.h>
3*48761c62SAndrew Jeffery #include <libpldm/bios.h>
4*48761c62SAndrew Jeffery #include <libpldm/utils.h>
5*48761c62SAndrew Jeffery 
6*48761c62SAndrew Jeffery #include <endian.h>
7*48761c62SAndrew Jeffery #include <string.h>
8*48761c62SAndrew Jeffery 
9*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_date_time_req(uint8_t instance_id,struct pldm_msg * msg)10*48761c62SAndrew Jeffery int encode_get_date_time_req(uint8_t instance_id, struct pldm_msg *msg)
11*48761c62SAndrew Jeffery {
12*48761c62SAndrew Jeffery 	if (msg == NULL) {
13*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
14*48761c62SAndrew Jeffery 	}
15*48761c62SAndrew Jeffery 
16*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
17*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
18*48761c62SAndrew Jeffery 	header.instance = instance_id;
19*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
20*48761c62SAndrew Jeffery 	header.command = PLDM_GET_DATE_TIME;
21*48761c62SAndrew Jeffery 	return pack_pldm_header(&header, &(msg->hdr));
22*48761c62SAndrew Jeffery }
23*48761c62SAndrew Jeffery 
24*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_date_time_resp(uint8_t instance_id,uint8_t completion_code,uint8_t seconds,uint8_t minutes,uint8_t hours,uint8_t day,uint8_t month,uint16_t year,struct pldm_msg * msg)25*48761c62SAndrew Jeffery int encode_get_date_time_resp(uint8_t instance_id, uint8_t completion_code,
26*48761c62SAndrew Jeffery 			      uint8_t seconds, uint8_t minutes, uint8_t hours,
27*48761c62SAndrew Jeffery 			      uint8_t day, uint8_t month, uint16_t year,
28*48761c62SAndrew Jeffery 			      struct pldm_msg *msg)
29*48761c62SAndrew Jeffery {
30*48761c62SAndrew Jeffery 	if (msg == NULL) {
31*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
32*48761c62SAndrew Jeffery 	}
33*48761c62SAndrew Jeffery 
34*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
35*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
36*48761c62SAndrew Jeffery 	header.instance = instance_id;
37*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
38*48761c62SAndrew Jeffery 	header.command = PLDM_GET_DATE_TIME;
39*48761c62SAndrew Jeffery 
40*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
41*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
42*48761c62SAndrew Jeffery 		return rc;
43*48761c62SAndrew Jeffery 	}
44*48761c62SAndrew Jeffery 
45*48761c62SAndrew Jeffery 	struct pldm_get_date_time_resp *response =
46*48761c62SAndrew Jeffery 		(struct pldm_get_date_time_resp *)msg->payload;
47*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
48*48761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
49*48761c62SAndrew Jeffery 		response->completion_code = completion_code;
50*48761c62SAndrew Jeffery 		response->seconds = seconds;
51*48761c62SAndrew Jeffery 		response->minutes = minutes;
52*48761c62SAndrew Jeffery 		response->hours = hours;
53*48761c62SAndrew Jeffery 		response->day = day;
54*48761c62SAndrew Jeffery 		response->month = month;
55*48761c62SAndrew Jeffery 		response->year = htole16(year);
56*48761c62SAndrew Jeffery 	}
57*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
58*48761c62SAndrew Jeffery }
59*48761c62SAndrew Jeffery 
60*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_date_time_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint8_t * seconds,uint8_t * minutes,uint8_t * hours,uint8_t * day,uint8_t * month,uint16_t * year)61*48761c62SAndrew Jeffery int decode_get_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
62*48761c62SAndrew Jeffery 			      uint8_t *completion_code, uint8_t *seconds,
63*48761c62SAndrew Jeffery 			      uint8_t *minutes, uint8_t *hours, uint8_t *day,
64*48761c62SAndrew Jeffery 			      uint8_t *month, uint16_t *year)
65*48761c62SAndrew Jeffery {
66*48761c62SAndrew Jeffery 	if (msg == NULL || seconds == NULL || minutes == NULL ||
67*48761c62SAndrew Jeffery 	    hours == NULL || day == NULL || month == NULL || year == NULL ||
68*48761c62SAndrew Jeffery 	    completion_code == NULL) {
69*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
70*48761c62SAndrew Jeffery 	}
71*48761c62SAndrew Jeffery 
72*48761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
73*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
74*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
75*48761c62SAndrew Jeffery 	}
76*48761c62SAndrew Jeffery 
77*48761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_DATE_TIME_RESP_BYTES) {
78*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
79*48761c62SAndrew Jeffery 	}
80*48761c62SAndrew Jeffery 
81*48761c62SAndrew Jeffery 	struct pldm_get_date_time_resp *response =
82*48761c62SAndrew Jeffery 		(struct pldm_get_date_time_resp *)msg->payload;
83*48761c62SAndrew Jeffery 
84*48761c62SAndrew Jeffery 	*seconds = response->seconds;
85*48761c62SAndrew Jeffery 	*minutes = response->minutes;
86*48761c62SAndrew Jeffery 	*hours = response->hours;
87*48761c62SAndrew Jeffery 	*day = response->day;
88*48761c62SAndrew Jeffery 	*month = response->month;
89*48761c62SAndrew Jeffery 	*year = le16toh(response->year);
90*48761c62SAndrew Jeffery 
91*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
92*48761c62SAndrew Jeffery }
93*48761c62SAndrew Jeffery 
94*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_date_time_req(uint8_t instance_id,uint8_t seconds,uint8_t minutes,uint8_t hours,uint8_t day,uint8_t month,uint16_t year,struct pldm_msg * msg,size_t payload_length)95*48761c62SAndrew Jeffery int encode_set_date_time_req(uint8_t instance_id, uint8_t seconds,
96*48761c62SAndrew Jeffery 			     uint8_t minutes, uint8_t hours, uint8_t day,
97*48761c62SAndrew Jeffery 			     uint8_t month, uint16_t year, struct pldm_msg *msg,
98*48761c62SAndrew Jeffery 			     size_t payload_length)
99*48761c62SAndrew Jeffery {
100*48761c62SAndrew Jeffery 	if (msg == NULL) {
101*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
102*48761c62SAndrew Jeffery 	}
103*48761c62SAndrew Jeffery 	if (payload_length != sizeof(struct pldm_set_date_time_req)) {
104*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
105*48761c62SAndrew Jeffery 	}
106*48761c62SAndrew Jeffery 
107*48761c62SAndrew Jeffery 	if (!is_time_legal(seconds, minutes, hours, day, month, year)) {
108*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
109*48761c62SAndrew Jeffery 	}
110*48761c62SAndrew Jeffery 
111*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
112*48761c62SAndrew Jeffery 	header.instance = instance_id;
113*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
114*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
115*48761c62SAndrew Jeffery 	header.command = PLDM_SET_DATE_TIME;
116*48761c62SAndrew Jeffery 
117*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
118*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
119*48761c62SAndrew Jeffery 		return rc;
120*48761c62SAndrew Jeffery 	}
121*48761c62SAndrew Jeffery 
122*48761c62SAndrew Jeffery 	struct pldm_set_date_time_req *request =
123*48761c62SAndrew Jeffery 		(struct pldm_set_date_time_req *)msg->payload;
124*48761c62SAndrew Jeffery 	request->seconds = dec2bcd8(seconds);
125*48761c62SAndrew Jeffery 	request->minutes = dec2bcd8(minutes);
126*48761c62SAndrew Jeffery 	request->hours = dec2bcd8(hours);
127*48761c62SAndrew Jeffery 	request->day = dec2bcd8(day);
128*48761c62SAndrew Jeffery 	request->month = dec2bcd8(month);
129*48761c62SAndrew Jeffery 	request->year = htole16(dec2bcd16(year));
130*48761c62SAndrew Jeffery 
131*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
132*48761c62SAndrew Jeffery }
133*48761c62SAndrew Jeffery 
134*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_date_time_req(const struct pldm_msg * msg,size_t payload_length,uint8_t * seconds,uint8_t * minutes,uint8_t * hours,uint8_t * day,uint8_t * month,uint16_t * year)135*48761c62SAndrew Jeffery int decode_set_date_time_req(const struct pldm_msg *msg, size_t payload_length,
136*48761c62SAndrew Jeffery 			     uint8_t *seconds, uint8_t *minutes, uint8_t *hours,
137*48761c62SAndrew Jeffery 			     uint8_t *day, uint8_t *month, uint16_t *year)
138*48761c62SAndrew Jeffery {
139*48761c62SAndrew Jeffery 	if (msg == NULL || seconds == NULL || minutes == NULL ||
140*48761c62SAndrew Jeffery 	    hours == NULL || day == NULL || month == NULL || year == NULL) {
141*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
142*48761c62SAndrew Jeffery 	}
143*48761c62SAndrew Jeffery 	if (payload_length != sizeof(struct pldm_set_date_time_req)) {
144*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
145*48761c62SAndrew Jeffery 	}
146*48761c62SAndrew Jeffery 
147*48761c62SAndrew Jeffery 	const struct pldm_set_date_time_req *request =
148*48761c62SAndrew Jeffery 		(struct pldm_set_date_time_req *)msg->payload;
149*48761c62SAndrew Jeffery 
150*48761c62SAndrew Jeffery 	*seconds = bcd2dec8(request->seconds);
151*48761c62SAndrew Jeffery 	*minutes = bcd2dec8(request->minutes);
152*48761c62SAndrew Jeffery 	*hours = bcd2dec8(request->hours);
153*48761c62SAndrew Jeffery 	*day = bcd2dec8(request->day);
154*48761c62SAndrew Jeffery 	*month = bcd2dec8(request->month);
155*48761c62SAndrew Jeffery 	*year = bcd2dec16(le16toh(request->year));
156*48761c62SAndrew Jeffery 
157*48761c62SAndrew Jeffery 	if (!is_time_legal(*seconds, *minutes, *hours, *day, *month, *year)) {
158*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
159*48761c62SAndrew Jeffery 	}
160*48761c62SAndrew Jeffery 
161*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
162*48761c62SAndrew Jeffery }
163*48761c62SAndrew Jeffery 
164*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_date_time_resp(uint8_t instance_id,uint8_t completion_code,struct pldm_msg * msg,size_t payload_length)165*48761c62SAndrew Jeffery int encode_set_date_time_resp(uint8_t instance_id, uint8_t completion_code,
166*48761c62SAndrew Jeffery 			      struct pldm_msg *msg, size_t payload_length)
167*48761c62SAndrew Jeffery {
168*48761c62SAndrew Jeffery 	if (msg == NULL) {
169*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
170*48761c62SAndrew Jeffery 	}
171*48761c62SAndrew Jeffery 	if (payload_length != sizeof(struct pldm_only_cc_resp)) {
172*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
173*48761c62SAndrew Jeffery 	}
174*48761c62SAndrew Jeffery 
175*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
176*48761c62SAndrew Jeffery 	header.instance = instance_id;
177*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
178*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
179*48761c62SAndrew Jeffery 	header.command = PLDM_SET_DATE_TIME;
180*48761c62SAndrew Jeffery 
181*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
182*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
183*48761c62SAndrew Jeffery 		return rc;
184*48761c62SAndrew Jeffery 	}
185*48761c62SAndrew Jeffery 
186*48761c62SAndrew Jeffery 	struct pldm_only_cc_resp *response =
187*48761c62SAndrew Jeffery 		(struct pldm_only_cc_resp *)msg->payload;
188*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
189*48761c62SAndrew Jeffery 
190*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
191*48761c62SAndrew Jeffery }
192*48761c62SAndrew Jeffery 
193*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_date_time_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code)194*48761c62SAndrew Jeffery int decode_set_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
195*48761c62SAndrew Jeffery 			      uint8_t *completion_code)
196*48761c62SAndrew Jeffery {
197*48761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL) {
198*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
199*48761c62SAndrew Jeffery 	}
200*48761c62SAndrew Jeffery 
201*48761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
202*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
203*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
204*48761c62SAndrew Jeffery 	}
205*48761c62SAndrew Jeffery 
206*48761c62SAndrew Jeffery 	if (payload_length != sizeof(struct pldm_only_cc_resp)) {
207*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
208*48761c62SAndrew Jeffery 	}
209*48761c62SAndrew Jeffery 
210*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
211*48761c62SAndrew Jeffery }
212*48761c62SAndrew Jeffery 
213*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_bios_table_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,uint8_t transfer_flag,uint8_t * table_data,size_t payload_length,struct pldm_msg * msg)214*48761c62SAndrew Jeffery int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
215*48761c62SAndrew Jeffery 			       uint32_t next_transfer_handle,
216*48761c62SAndrew Jeffery 			       uint8_t transfer_flag, uint8_t *table_data,
217*48761c62SAndrew Jeffery 			       size_t payload_length, struct pldm_msg *msg)
218*48761c62SAndrew Jeffery {
219*48761c62SAndrew Jeffery 	if (msg == NULL) {
220*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
221*48761c62SAndrew Jeffery 	}
222*48761c62SAndrew Jeffery 
223*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
224*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
225*48761c62SAndrew Jeffery 	header.instance = instance_id;
226*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
227*48761c62SAndrew Jeffery 	header.command = PLDM_GET_BIOS_TABLE;
228*48761c62SAndrew Jeffery 
229*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
230*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
231*48761c62SAndrew Jeffery 		return rc;
232*48761c62SAndrew Jeffery 	}
233*48761c62SAndrew Jeffery 
234*48761c62SAndrew Jeffery 	struct pldm_get_bios_table_resp *response =
235*48761c62SAndrew Jeffery 		(struct pldm_get_bios_table_resp *)msg->payload;
236*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
237*48761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
238*48761c62SAndrew Jeffery 		response->next_transfer_handle = htole32(next_transfer_handle);
239*48761c62SAndrew Jeffery 		response->transfer_flag = transfer_flag;
240*48761c62SAndrew Jeffery 		if (table_data != NULL &&
241*48761c62SAndrew Jeffery 		    payload_length > (sizeof(struct pldm_msg_hdr) +
242*48761c62SAndrew Jeffery 				      PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES)) {
243*48761c62SAndrew Jeffery 			memcpy(response->table_data, table_data,
244*48761c62SAndrew Jeffery 			       payload_length -
245*48761c62SAndrew Jeffery 				       (sizeof(struct pldm_msg_hdr) +
246*48761c62SAndrew Jeffery 					PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES));
247*48761c62SAndrew Jeffery 		}
248*48761c62SAndrew Jeffery 	}
249*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
250*48761c62SAndrew Jeffery }
251*48761c62SAndrew Jeffery 
252*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_bios_table_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_op_flag,uint8_t table_type,struct pldm_msg * msg)253*48761c62SAndrew Jeffery int encode_get_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
254*48761c62SAndrew Jeffery 			      uint8_t transfer_op_flag, uint8_t table_type,
255*48761c62SAndrew Jeffery 			      struct pldm_msg *msg)
256*48761c62SAndrew Jeffery {
257*48761c62SAndrew Jeffery 	if (msg == NULL) {
258*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
259*48761c62SAndrew Jeffery 	}
260*48761c62SAndrew Jeffery 
261*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
262*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
263*48761c62SAndrew Jeffery 	header.instance = instance_id;
264*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
265*48761c62SAndrew Jeffery 	header.command = PLDM_GET_BIOS_TABLE;
266*48761c62SAndrew Jeffery 
267*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
268*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
269*48761c62SAndrew Jeffery 		return rc;
270*48761c62SAndrew Jeffery 	}
271*48761c62SAndrew Jeffery 
272*48761c62SAndrew Jeffery 	struct pldm_get_bios_table_req *request =
273*48761c62SAndrew Jeffery 		(struct pldm_get_bios_table_req *)msg->payload;
274*48761c62SAndrew Jeffery 
275*48761c62SAndrew Jeffery 	request->transfer_handle = htole32(transfer_handle);
276*48761c62SAndrew Jeffery 	request->transfer_op_flag = transfer_op_flag;
277*48761c62SAndrew Jeffery 	request->table_type = table_type;
278*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
279*48761c62SAndrew Jeffery }
280*48761c62SAndrew Jeffery 
281*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_bios_table_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_op_flag,uint8_t * table_type)282*48761c62SAndrew Jeffery int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
283*48761c62SAndrew Jeffery 			      uint32_t *transfer_handle,
284*48761c62SAndrew Jeffery 			      uint8_t *transfer_op_flag, uint8_t *table_type)
285*48761c62SAndrew Jeffery {
286*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_op_flag == NULL || table_type == NULL ||
287*48761c62SAndrew Jeffery 	    transfer_handle == NULL) {
288*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
289*48761c62SAndrew Jeffery 	}
290*48761c62SAndrew Jeffery 
291*48761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_BIOS_TABLE_REQ_BYTES) {
292*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
293*48761c62SAndrew Jeffery 	}
294*48761c62SAndrew Jeffery 
295*48761c62SAndrew Jeffery 	struct pldm_get_bios_table_req *request =
296*48761c62SAndrew Jeffery 		(struct pldm_get_bios_table_req *)msg->payload;
297*48761c62SAndrew Jeffery 	*transfer_handle = le32toh(request->transfer_handle);
298*48761c62SAndrew Jeffery 	*transfer_op_flag = request->transfer_op_flag;
299*48761c62SAndrew Jeffery 	*table_type = request->table_type;
300*48761c62SAndrew Jeffery 
301*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
302*48761c62SAndrew Jeffery }
303*48761c62SAndrew Jeffery 
304*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_bios_table_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle,uint8_t * transfer_flag,size_t * bios_table_offset)305*48761c62SAndrew Jeffery int decode_get_bios_table_resp(const struct pldm_msg *msg,
306*48761c62SAndrew Jeffery 			       size_t payload_length, uint8_t *completion_code,
307*48761c62SAndrew Jeffery 			       uint32_t *next_transfer_handle,
308*48761c62SAndrew Jeffery 			       uint8_t *transfer_flag,
309*48761c62SAndrew Jeffery 			       size_t *bios_table_offset)
310*48761c62SAndrew Jeffery 
311*48761c62SAndrew Jeffery {
312*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_flag == NULL ||
313*48761c62SAndrew Jeffery 	    next_transfer_handle == NULL || completion_code == NULL) {
314*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
315*48761c62SAndrew Jeffery 	}
316*48761c62SAndrew Jeffery 	if (payload_length <= PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES) {
317*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
318*48761c62SAndrew Jeffery 	}
319*48761c62SAndrew Jeffery 
320*48761c62SAndrew Jeffery 	struct pldm_get_bios_table_resp *response =
321*48761c62SAndrew Jeffery 		(struct pldm_get_bios_table_resp *)msg->payload;
322*48761c62SAndrew Jeffery 
323*48761c62SAndrew Jeffery 	*completion_code = response->completion_code;
324*48761c62SAndrew Jeffery 
325*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
326*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
327*48761c62SAndrew Jeffery 	}
328*48761c62SAndrew Jeffery 
329*48761c62SAndrew Jeffery 	*next_transfer_handle = le32toh(response->next_transfer_handle);
330*48761c62SAndrew Jeffery 	*transfer_flag = response->transfer_flag;
331*48761c62SAndrew Jeffery 
332*48761c62SAndrew Jeffery 	*bios_table_offset = sizeof(*completion_code) +
333*48761c62SAndrew Jeffery 			     sizeof(*next_transfer_handle) +
334*48761c62SAndrew Jeffery 			     sizeof(*transfer_flag);
335*48761c62SAndrew Jeffery 
336*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
337*48761c62SAndrew Jeffery }
338*48761c62SAndrew Jeffery 
339*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_bios_attribute_current_value_by_handle_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_op_flag,uint16_t attribute_handle,struct pldm_msg * msg)340*48761c62SAndrew Jeffery int encode_get_bios_attribute_current_value_by_handle_req(
341*48761c62SAndrew Jeffery 	uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
342*48761c62SAndrew Jeffery 	uint16_t attribute_handle, struct pldm_msg *msg)
343*48761c62SAndrew Jeffery {
344*48761c62SAndrew Jeffery 	if (msg == NULL) {
345*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
346*48761c62SAndrew Jeffery 	}
347*48761c62SAndrew Jeffery 
348*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
349*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
350*48761c62SAndrew Jeffery 	header.instance = instance_id;
351*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
352*48761c62SAndrew Jeffery 	header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
353*48761c62SAndrew Jeffery 
354*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
355*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
356*48761c62SAndrew Jeffery 		return rc;
357*48761c62SAndrew Jeffery 	}
358*48761c62SAndrew Jeffery 
359*48761c62SAndrew Jeffery 	struct pldm_get_bios_attribute_current_value_by_handle_req *request =
360*48761c62SAndrew Jeffery 		(struct pldm_get_bios_attribute_current_value_by_handle_req *)
361*48761c62SAndrew Jeffery 			msg->payload;
362*48761c62SAndrew Jeffery 
363*48761c62SAndrew Jeffery 	request->transfer_handle = htole32(transfer_handle);
364*48761c62SAndrew Jeffery 	request->transfer_op_flag = transfer_op_flag;
365*48761c62SAndrew Jeffery 	request->attribute_handle = htole16(attribute_handle);
366*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
367*48761c62SAndrew Jeffery }
368*48761c62SAndrew Jeffery 
369*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_bios_attribute_current_value_by_handle_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle,uint8_t * transfer_flag,struct variable_field * attribute_data)370*48761c62SAndrew Jeffery int decode_get_bios_attribute_current_value_by_handle_resp(
371*48761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
372*48761c62SAndrew Jeffery 	uint8_t *completion_code, uint32_t *next_transfer_handle,
373*48761c62SAndrew Jeffery 	uint8_t *transfer_flag, struct variable_field *attribute_data)
374*48761c62SAndrew Jeffery {
375*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_flag == NULL ||
376*48761c62SAndrew Jeffery 	    next_transfer_handle == NULL || completion_code == NULL) {
377*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
378*48761c62SAndrew Jeffery 	}
379*48761c62SAndrew Jeffery 
380*48761c62SAndrew Jeffery 	struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
381*48761c62SAndrew Jeffery 		(struct pldm_get_bios_attribute_current_value_by_handle_resp *)
382*48761c62SAndrew Jeffery 			msg->payload;
383*48761c62SAndrew Jeffery 
384*48761c62SAndrew Jeffery 	*completion_code = response->completion_code;
385*48761c62SAndrew Jeffery 
386*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
387*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
388*48761c62SAndrew Jeffery 	}
389*48761c62SAndrew Jeffery 
390*48761c62SAndrew Jeffery 	if (payload_length <=
391*48761c62SAndrew Jeffery 	    PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES) {
392*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
393*48761c62SAndrew Jeffery 	}
394*48761c62SAndrew Jeffery 
395*48761c62SAndrew Jeffery 	*next_transfer_handle = le32toh(response->next_transfer_handle);
396*48761c62SAndrew Jeffery 	*transfer_flag = response->transfer_flag;
397*48761c62SAndrew Jeffery 
398*48761c62SAndrew Jeffery 	attribute_data->ptr = response->attribute_data;
399*48761c62SAndrew Jeffery 	attribute_data->length = payload_length - sizeof(*response) + 1;
400*48761c62SAndrew Jeffery 
401*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
402*48761c62SAndrew Jeffery }
403*48761c62SAndrew Jeffery 
404*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_get_bios_attribute_current_value_by_handle_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_op_flag,uint16_t * attribute_handle)405*48761c62SAndrew Jeffery int decode_get_bios_attribute_current_value_by_handle_req(
406*48761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
407*48761c62SAndrew Jeffery 	uint32_t *transfer_handle, uint8_t *transfer_op_flag,
408*48761c62SAndrew Jeffery 	uint16_t *attribute_handle)
409*48761c62SAndrew Jeffery {
410*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_handle == NULL ||
411*48761c62SAndrew Jeffery 	    transfer_op_flag == NULL || attribute_handle == NULL) {
412*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
413*48761c62SAndrew Jeffery 	}
414*48761c62SAndrew Jeffery 
415*48761c62SAndrew Jeffery 	if (payload_length != PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES) {
416*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
417*48761c62SAndrew Jeffery 	}
418*48761c62SAndrew Jeffery 
419*48761c62SAndrew Jeffery 	struct pldm_get_bios_attribute_current_value_by_handle_req *request =
420*48761c62SAndrew Jeffery 		(struct pldm_get_bios_attribute_current_value_by_handle_req *)
421*48761c62SAndrew Jeffery 			msg->payload;
422*48761c62SAndrew Jeffery 	*transfer_handle = le32toh(request->transfer_handle);
423*48761c62SAndrew Jeffery 	*transfer_op_flag = request->transfer_op_flag;
424*48761c62SAndrew Jeffery 	*attribute_handle = le16toh(request->attribute_handle);
425*48761c62SAndrew Jeffery 
426*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
427*48761c62SAndrew Jeffery }
428*48761c62SAndrew Jeffery 
429*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_get_bios_current_value_by_handle_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,uint8_t transfer_flag,const uint8_t * attribute_data,size_t attribute_length,struct pldm_msg * msg)430*48761c62SAndrew Jeffery int encode_get_bios_current_value_by_handle_resp(uint8_t instance_id,
431*48761c62SAndrew Jeffery 						 uint8_t completion_code,
432*48761c62SAndrew Jeffery 						 uint32_t next_transfer_handle,
433*48761c62SAndrew Jeffery 						 uint8_t transfer_flag,
434*48761c62SAndrew Jeffery 						 const uint8_t *attribute_data,
435*48761c62SAndrew Jeffery 						 size_t attribute_length,
436*48761c62SAndrew Jeffery 						 struct pldm_msg *msg)
437*48761c62SAndrew Jeffery {
438*48761c62SAndrew Jeffery 	if (msg == NULL || attribute_data == NULL) {
439*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
440*48761c62SAndrew Jeffery 	}
441*48761c62SAndrew Jeffery 
442*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
443*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
444*48761c62SAndrew Jeffery 	header.instance = instance_id;
445*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
446*48761c62SAndrew Jeffery 	header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
447*48761c62SAndrew Jeffery 
448*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
449*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
450*48761c62SAndrew Jeffery 		return rc;
451*48761c62SAndrew Jeffery 	}
452*48761c62SAndrew Jeffery 
453*48761c62SAndrew Jeffery 	struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
454*48761c62SAndrew Jeffery 		(struct pldm_get_bios_attribute_current_value_by_handle_resp *)
455*48761c62SAndrew Jeffery 			msg->payload;
456*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
457*48761c62SAndrew Jeffery 	if (response->completion_code == PLDM_SUCCESS) {
458*48761c62SAndrew Jeffery 		response->next_transfer_handle = htole32(next_transfer_handle);
459*48761c62SAndrew Jeffery 		response->transfer_flag = transfer_flag;
460*48761c62SAndrew Jeffery 		if (attribute_data != NULL) {
461*48761c62SAndrew Jeffery 			memcpy(response->attribute_data, attribute_data,
462*48761c62SAndrew Jeffery 			       attribute_length);
463*48761c62SAndrew Jeffery 		}
464*48761c62SAndrew Jeffery 	}
465*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
466*48761c62SAndrew Jeffery }
467*48761c62SAndrew Jeffery 
468*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_bios_attribute_current_value_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_flag,const uint8_t * attribute_data,size_t attribute_length,struct pldm_msg * msg,size_t payload_length)469*48761c62SAndrew Jeffery int encode_set_bios_attribute_current_value_req(
470*48761c62SAndrew Jeffery 	uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_flag,
471*48761c62SAndrew Jeffery 	const uint8_t *attribute_data, size_t attribute_length,
472*48761c62SAndrew Jeffery 	struct pldm_msg *msg, size_t payload_length)
473*48761c62SAndrew Jeffery {
474*48761c62SAndrew Jeffery 	if (msg == NULL || attribute_data == NULL) {
475*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
476*48761c62SAndrew Jeffery 	}
477*48761c62SAndrew Jeffery 	if (PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES + attribute_length !=
478*48761c62SAndrew Jeffery 	    payload_length) {
479*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
480*48761c62SAndrew Jeffery 	}
481*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
482*48761c62SAndrew Jeffery 	header.instance = instance_id;
483*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
484*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
485*48761c62SAndrew Jeffery 	header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
486*48761c62SAndrew Jeffery 
487*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
488*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
489*48761c62SAndrew Jeffery 		return rc;
490*48761c62SAndrew Jeffery 	}
491*48761c62SAndrew Jeffery 
492*48761c62SAndrew Jeffery 	struct pldm_set_bios_attribute_current_value_req *request =
493*48761c62SAndrew Jeffery 		(struct pldm_set_bios_attribute_current_value_req *)msg->payload;
494*48761c62SAndrew Jeffery 	request->transfer_handle = htole32(transfer_handle);
495*48761c62SAndrew Jeffery 	request->transfer_flag = transfer_flag;
496*48761c62SAndrew Jeffery 	memcpy(request->attribute_data, attribute_data, attribute_length);
497*48761c62SAndrew Jeffery 
498*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
499*48761c62SAndrew Jeffery }
500*48761c62SAndrew Jeffery 
501*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_bios_attribute_current_value_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle)502*48761c62SAndrew Jeffery int decode_set_bios_attribute_current_value_resp(const struct pldm_msg *msg,
503*48761c62SAndrew Jeffery 						 size_t payload_length,
504*48761c62SAndrew Jeffery 						 uint8_t *completion_code,
505*48761c62SAndrew Jeffery 						 uint32_t *next_transfer_handle)
506*48761c62SAndrew Jeffery {
507*48761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
508*48761c62SAndrew Jeffery 	    next_transfer_handle == NULL) {
509*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
510*48761c62SAndrew Jeffery 	}
511*48761c62SAndrew Jeffery 
512*48761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
513*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
514*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
515*48761c62SAndrew Jeffery 	}
516*48761c62SAndrew Jeffery 
517*48761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES) {
518*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
519*48761c62SAndrew Jeffery 	}
520*48761c62SAndrew Jeffery 
521*48761c62SAndrew Jeffery 	struct pldm_set_bios_attribute_current_value_resp *response =
522*48761c62SAndrew Jeffery 		(struct pldm_set_bios_attribute_current_value_resp *)
523*48761c62SAndrew Jeffery 			msg->payload;
524*48761c62SAndrew Jeffery 
525*48761c62SAndrew Jeffery 	*next_transfer_handle = le32toh(response->next_transfer_handle);
526*48761c62SAndrew Jeffery 
527*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
528*48761c62SAndrew Jeffery }
529*48761c62SAndrew Jeffery 
530*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_bios_attribute_current_value_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_flag,struct variable_field * attribute)531*48761c62SAndrew Jeffery int decode_set_bios_attribute_current_value_req(
532*48761c62SAndrew Jeffery 	const struct pldm_msg *msg, size_t payload_length,
533*48761c62SAndrew Jeffery 	uint32_t *transfer_handle, uint8_t *transfer_flag,
534*48761c62SAndrew Jeffery 	struct variable_field *attribute)
535*48761c62SAndrew Jeffery {
536*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
537*48761c62SAndrew Jeffery 	    attribute == NULL) {
538*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
539*48761c62SAndrew Jeffery 	}
540*48761c62SAndrew Jeffery 	if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
541*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
542*48761c62SAndrew Jeffery 	}
543*48761c62SAndrew Jeffery 
544*48761c62SAndrew Jeffery 	struct pldm_set_bios_attribute_current_value_req *request =
545*48761c62SAndrew Jeffery 		(struct pldm_set_bios_attribute_current_value_req *)msg->payload;
546*48761c62SAndrew Jeffery 	*transfer_handle = le32toh(request->transfer_handle);
547*48761c62SAndrew Jeffery 	*transfer_flag = request->transfer_flag;
548*48761c62SAndrew Jeffery 	attribute->length =
549*48761c62SAndrew Jeffery 		payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES;
550*48761c62SAndrew Jeffery 	attribute->ptr = request->attribute_data;
551*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
552*48761c62SAndrew Jeffery }
553*48761c62SAndrew Jeffery 
554*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_bios_attribute_current_value_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,struct pldm_msg * msg)555*48761c62SAndrew Jeffery int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
556*48761c62SAndrew Jeffery 						 uint8_t completion_code,
557*48761c62SAndrew Jeffery 						 uint32_t next_transfer_handle,
558*48761c62SAndrew Jeffery 						 struct pldm_msg *msg)
559*48761c62SAndrew Jeffery {
560*48761c62SAndrew Jeffery 	if (msg == NULL) {
561*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
562*48761c62SAndrew Jeffery 	}
563*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
564*48761c62SAndrew Jeffery 	header.instance = instance_id;
565*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
566*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
567*48761c62SAndrew Jeffery 	header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
568*48761c62SAndrew Jeffery 
569*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &msg->hdr);
570*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
571*48761c62SAndrew Jeffery 		return rc;
572*48761c62SAndrew Jeffery 	}
573*48761c62SAndrew Jeffery 
574*48761c62SAndrew Jeffery 	struct pldm_set_bios_attribute_current_value_resp *response =
575*48761c62SAndrew Jeffery 		(struct pldm_set_bios_attribute_current_value_resp *)
576*48761c62SAndrew Jeffery 			msg->payload;
577*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
578*48761c62SAndrew Jeffery 	response->next_transfer_handle = htole32(next_transfer_handle);
579*48761c62SAndrew Jeffery 
580*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
581*48761c62SAndrew Jeffery }
582*48761c62SAndrew Jeffery 
583*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_bios_table_req(uint8_t instance_id,uint32_t transfer_handle,uint8_t transfer_flag,uint8_t table_type,const uint8_t * table_data,size_t table_length,struct pldm_msg * msg,size_t payload_length)584*48761c62SAndrew Jeffery int encode_set_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
585*48761c62SAndrew Jeffery 			      uint8_t transfer_flag, uint8_t table_type,
586*48761c62SAndrew Jeffery 			      const uint8_t *table_data, size_t table_length,
587*48761c62SAndrew Jeffery 			      struct pldm_msg *msg, size_t payload_length)
588*48761c62SAndrew Jeffery {
589*48761c62SAndrew Jeffery 	if (msg == NULL || table_data == NULL) {
590*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
591*48761c62SAndrew Jeffery 	}
592*48761c62SAndrew Jeffery 
593*48761c62SAndrew Jeffery 	if (PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES + table_length !=
594*48761c62SAndrew Jeffery 	    payload_length) {
595*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
596*48761c62SAndrew Jeffery 	}
597*48761c62SAndrew Jeffery 
598*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
599*48761c62SAndrew Jeffery 	header.instance = instance_id;
600*48761c62SAndrew Jeffery 	header.msg_type = PLDM_REQUEST;
601*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
602*48761c62SAndrew Jeffery 	header.command = PLDM_SET_BIOS_TABLE;
603*48761c62SAndrew Jeffery 
604*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
605*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
606*48761c62SAndrew Jeffery 		return rc;
607*48761c62SAndrew Jeffery 	}
608*48761c62SAndrew Jeffery 
609*48761c62SAndrew Jeffery 	struct pldm_set_bios_table_req *request =
610*48761c62SAndrew Jeffery 		(struct pldm_set_bios_table_req *)msg->payload;
611*48761c62SAndrew Jeffery 	request->transfer_handle = htole32(transfer_handle);
612*48761c62SAndrew Jeffery 	request->transfer_flag = transfer_flag;
613*48761c62SAndrew Jeffery 	request->table_type = table_type;
614*48761c62SAndrew Jeffery 	memcpy(request->table_data, table_data, table_length);
615*48761c62SAndrew Jeffery 
616*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
617*48761c62SAndrew Jeffery }
618*48761c62SAndrew Jeffery 
619*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_bios_table_resp(const struct pldm_msg * msg,size_t payload_length,uint8_t * completion_code,uint32_t * next_transfer_handle)620*48761c62SAndrew Jeffery int decode_set_bios_table_resp(const struct pldm_msg *msg,
621*48761c62SAndrew Jeffery 			       size_t payload_length, uint8_t *completion_code,
622*48761c62SAndrew Jeffery 			       uint32_t *next_transfer_handle)
623*48761c62SAndrew Jeffery {
624*48761c62SAndrew Jeffery 	if (msg == NULL || completion_code == NULL ||
625*48761c62SAndrew Jeffery 	    next_transfer_handle == NULL) {
626*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
627*48761c62SAndrew Jeffery 	}
628*48761c62SAndrew Jeffery 
629*48761c62SAndrew Jeffery 	*completion_code = msg->payload[0];
630*48761c62SAndrew Jeffery 	if (PLDM_SUCCESS != *completion_code) {
631*48761c62SAndrew Jeffery 		return PLDM_SUCCESS;
632*48761c62SAndrew Jeffery 	}
633*48761c62SAndrew Jeffery 
634*48761c62SAndrew Jeffery 	if (payload_length != PLDM_SET_BIOS_TABLE_RESP_BYTES) {
635*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
636*48761c62SAndrew Jeffery 	}
637*48761c62SAndrew Jeffery 
638*48761c62SAndrew Jeffery 	struct pldm_set_bios_table_resp *response =
639*48761c62SAndrew Jeffery 		(struct pldm_set_bios_table_resp *)msg->payload;
640*48761c62SAndrew Jeffery 
641*48761c62SAndrew Jeffery 	*next_transfer_handle = le32toh(response->next_transfer_handle);
642*48761c62SAndrew Jeffery 
643*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
644*48761c62SAndrew Jeffery }
645*48761c62SAndrew Jeffery 
646*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
encode_set_bios_table_resp(uint8_t instance_id,uint8_t completion_code,uint32_t next_transfer_handle,struct pldm_msg * msg)647*48761c62SAndrew Jeffery int encode_set_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
648*48761c62SAndrew Jeffery 			       uint32_t next_transfer_handle,
649*48761c62SAndrew Jeffery 			       struct pldm_msg *msg)
650*48761c62SAndrew Jeffery {
651*48761c62SAndrew Jeffery 	if (msg == NULL) {
652*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
653*48761c62SAndrew Jeffery 	}
654*48761c62SAndrew Jeffery 
655*48761c62SAndrew Jeffery 	struct pldm_header_info header = { 0 };
656*48761c62SAndrew Jeffery 	header.instance = instance_id;
657*48761c62SAndrew Jeffery 	header.msg_type = PLDM_RESPONSE;
658*48761c62SAndrew Jeffery 	header.pldm_type = PLDM_BIOS;
659*48761c62SAndrew Jeffery 	header.command = PLDM_SET_BIOS_TABLE;
660*48761c62SAndrew Jeffery 
661*48761c62SAndrew Jeffery 	uint8_t rc = pack_pldm_header(&header, &(msg->hdr));
662*48761c62SAndrew Jeffery 	if (rc != PLDM_SUCCESS) {
663*48761c62SAndrew Jeffery 		return rc;
664*48761c62SAndrew Jeffery 	}
665*48761c62SAndrew Jeffery 
666*48761c62SAndrew Jeffery 	struct pldm_set_bios_table_resp *response =
667*48761c62SAndrew Jeffery 		(struct pldm_set_bios_table_resp *)msg->payload;
668*48761c62SAndrew Jeffery 	response->completion_code = completion_code;
669*48761c62SAndrew Jeffery 	response->next_transfer_handle = htole32(next_transfer_handle);
670*48761c62SAndrew Jeffery 
671*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
672*48761c62SAndrew Jeffery }
673*48761c62SAndrew Jeffery 
674*48761c62SAndrew Jeffery LIBPLDM_ABI_STABLE
decode_set_bios_table_req(const struct pldm_msg * msg,size_t payload_length,uint32_t * transfer_handle,uint8_t * transfer_flag,uint8_t * table_type,struct variable_field * table)675*48761c62SAndrew Jeffery int decode_set_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
676*48761c62SAndrew Jeffery 			      uint32_t *transfer_handle, uint8_t *transfer_flag,
677*48761c62SAndrew Jeffery 			      uint8_t *table_type, struct variable_field *table)
678*48761c62SAndrew Jeffery {
679*48761c62SAndrew Jeffery 	if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
680*48761c62SAndrew Jeffery 	    table_type == NULL || table == NULL) {
681*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_DATA;
682*48761c62SAndrew Jeffery 	}
683*48761c62SAndrew Jeffery 
684*48761c62SAndrew Jeffery 	if (payload_length < PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES) {
685*48761c62SAndrew Jeffery 		return PLDM_ERROR_INVALID_LENGTH;
686*48761c62SAndrew Jeffery 	}
687*48761c62SAndrew Jeffery 
688*48761c62SAndrew Jeffery 	struct pldm_set_bios_table_req *request =
689*48761c62SAndrew Jeffery 		(struct pldm_set_bios_table_req *)msg->payload;
690*48761c62SAndrew Jeffery 	*transfer_handle = le32toh(request->transfer_handle);
691*48761c62SAndrew Jeffery 	*transfer_flag = request->transfer_flag;
692*48761c62SAndrew Jeffery 	*table_type = request->table_type;
693*48761c62SAndrew Jeffery 	table->length = payload_length - PLDM_SET_BIOS_TABLE_MIN_REQ_BYTES;
694*48761c62SAndrew Jeffery 	table->ptr = request->table_data;
695*48761c62SAndrew Jeffery 
696*48761c62SAndrew Jeffery 	return PLDM_SUCCESS;
697*48761c62SAndrew Jeffery }
698