blob: 151ba2995e7cd5b6a1dd5e36cb23f159c03cc7b4 [file] [log] [blame]
Sridevi Rameshd3d5fa82019-10-29 11:45:16 -05001#include "bios.h"
Xiaochao Ma39ae2a92019-11-12 20:30:34 +08002#include "utils.h"
Sampa Misra032bd502019-03-06 05:03:22 -06003#include <endian.h>
Xiaochao Ma39ae2a92019-11-12 20:30:34 +08004#include <stdbool.h>
Sampa Misra032bd502019-03-06 05:03:22 -06005#include <string.h>
6
Sampa Misra032bd502019-03-06 05:03:22 -06007int encode_get_date_time_req(uint8_t instance_id, struct pldm_msg *msg)
8{
9 struct pldm_header_info header = {0};
10
11 if (msg == NULL) {
12 return PLDM_ERROR_INVALID_DATA;
13 }
14
15 header.msg_type = PLDM_REQUEST;
16 header.instance = instance_id;
17 header.pldm_type = PLDM_BIOS;
18 header.command = PLDM_GET_DATE_TIME;
19 return pack_pldm_header(&header, &(msg->hdr));
20}
21
22int encode_get_date_time_resp(uint8_t instance_id, uint8_t completion_code,
23 uint8_t seconds, uint8_t minutes, uint8_t hours,
24 uint8_t day, uint8_t month, uint16_t year,
25 struct pldm_msg *msg)
26{
27 struct pldm_header_info header = {0};
28 int rc = PLDM_SUCCESS;
29
30 if (msg == NULL) {
31 return PLDM_ERROR_INVALID_DATA;
32 }
33
Sampa Misra032bd502019-03-06 05:03:22 -060034 header.msg_type = PLDM_RESPONSE;
35 header.instance = instance_id;
36 header.pldm_type = PLDM_BIOS;
37 header.command = PLDM_GET_DATE_TIME;
Zahed Hossain43264522019-06-04 02:21:03 -050038
Priyanga5dcd1802019-06-10 01:50:39 -050039 struct pldm_get_date_time_resp *response =
40 (struct pldm_get_date_time_resp *)msg->payload;
41
Sampa Misra032bd502019-03-06 05:03:22 -060042 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
43 return rc;
44 }
45
Priyanga5dcd1802019-06-10 01:50:39 -050046 response->completion_code = completion_code;
47 if (response->completion_code == PLDM_SUCCESS) {
48 response->completion_code = completion_code;
49 response->seconds = seconds;
50 response->minutes = minutes;
51 response->hours = hours;
52 response->day = day;
53 response->month = month;
54 response->year = htole16(year);
Zahed Hossain43264522019-06-04 02:21:03 -050055 }
Sampa Misra032bd502019-03-06 05:03:22 -060056 return PLDM_SUCCESS;
57}
58
Zahed Hossain223a73d2019-07-04 12:46:18 -050059int decode_get_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
Sampa Misra032bd502019-03-06 05:03:22 -060060 uint8_t *completion_code, uint8_t *seconds,
61 uint8_t *minutes, uint8_t *hours, uint8_t *day,
62 uint8_t *month, uint16_t *year)
63{
64 if (msg == NULL || seconds == NULL || minutes == NULL ||
65 hours == NULL || day == NULL || month == NULL || year == NULL ||
66 completion_code == NULL) {
67 return PLDM_ERROR_INVALID_DATA;
68 }
69
George Liu684a7162019-12-06 15:10:52 +080070 *completion_code = msg->payload[0];
71 if (PLDM_SUCCESS != *completion_code) {
72 return PLDM_SUCCESS;
73 }
74
vkaverapa6575b82019-04-03 05:33:52 -050075 if (payload_length != PLDM_GET_DATE_TIME_RESP_BYTES) {
76 return PLDM_ERROR_INVALID_LENGTH;
77 }
78
Priyanga5dcd1802019-06-10 01:50:39 -050079 struct pldm_get_date_time_resp *response =
Zahed Hossain223a73d2019-07-04 12:46:18 -050080 (struct pldm_get_date_time_resp *)msg->payload;
Priyanga5dcd1802019-06-10 01:50:39 -050081
Priyanga5dcd1802019-06-10 01:50:39 -050082 *seconds = response->seconds;
83 *minutes = response->minutes;
84 *hours = response->hours;
85 *day = response->day;
86 *month = response->month;
87 *year = le16toh(response->year);
Sampa Misra032bd502019-03-06 05:03:22 -060088
89 return PLDM_SUCCESS;
90}
Sampa Misrab37be312019-07-03 02:26:41 -050091
Xiaochao Ma39ae2a92019-11-12 20:30:34 +080092int encode_set_date_time_req(uint8_t instance_id, uint8_t seconds,
93 uint8_t minutes, uint8_t hours, uint8_t day,
94 uint8_t month, uint16_t year, struct pldm_msg *msg,
95 size_t payload_length)
96{
97 struct pldm_header_info header = {0};
98
99 if (msg == NULL) {
100 return PLDM_ERROR_INVALID_DATA;
101 }
102 if (payload_length != sizeof(struct pldm_set_date_time_req)) {
103 return PLDM_ERROR_INVALID_LENGTH;
104 }
105
106 if (!is_time_legal(seconds, minutes, hours, day, month, year)) {
107 return PLDM_ERROR_INVALID_DATA;
108 }
109 header.instance = instance_id;
110 header.msg_type = PLDM_REQUEST;
111 header.pldm_type = PLDM_BIOS;
112 header.command = PLDM_SET_DATE_TIME;
113 pack_pldm_header(&header, &msg->hdr);
114
115 struct pldm_set_date_time_req *request =
116 (struct pldm_set_date_time_req *)msg->payload;
117 request->seconds = dec2bcd8(seconds);
118 request->minutes = dec2bcd8(minutes);
119 request->hours = dec2bcd8(hours);
120 request->day = dec2bcd8(day);
121 request->month = dec2bcd8(month);
122 request->year = htole16(dec2bcd16(year));
123
124 return PLDM_SUCCESS;
125}
126
127int decode_set_date_time_req(const struct pldm_msg *msg, size_t payload_length,
128 uint8_t *seconds, uint8_t *minutes, uint8_t *hours,
129 uint8_t *day, uint8_t *month, uint16_t *year)
130{
131 if (msg == NULL || seconds == NULL || minutes == NULL ||
132 hours == NULL || day == NULL || month == NULL || year == NULL) {
133 return PLDM_ERROR_INVALID_DATA;
134 }
135 if (payload_length != sizeof(struct pldm_set_date_time_req)) {
136 return PLDM_ERROR_INVALID_LENGTH;
137 }
138
139 const struct pldm_set_date_time_req *request =
140 (struct pldm_set_date_time_req *)msg->payload;
141
142 *seconds = bcd2dec8(request->seconds);
143 *minutes = bcd2dec8(request->minutes);
144 *hours = bcd2dec8(request->hours);
145 *day = bcd2dec8(request->day);
146 *month = bcd2dec8(request->month);
147 *year = bcd2dec16(le16toh(request->year));
148
149 if (!is_time_legal(*seconds, *minutes, *hours, *day, *month, *year)) {
150 return PLDM_ERROR_INVALID_DATA;
151 }
152
153 return PLDM_SUCCESS;
154}
155
156int encode_set_date_time_resp(uint8_t instance_id, uint8_t completion_code,
157 struct pldm_msg *msg, size_t payload_length)
158{
159 struct pldm_header_info header = {0};
160
161 if (msg == NULL) {
162 return PLDM_ERROR_INVALID_DATA;
163 }
164 if (payload_length != sizeof(struct pldm_only_cc_resp)) {
165 return PLDM_ERROR_INVALID_LENGTH;
166 }
167
168 header.instance = instance_id;
169 header.msg_type = PLDM_RESPONSE;
170 header.pldm_type = PLDM_BIOS;
171 header.command = PLDM_SET_DATE_TIME;
172 int rc = pack_pldm_header(&header, &msg->hdr);
173 if (rc != PLDM_SUCCESS) {
174 return rc;
175 }
176
177 struct pldm_only_cc_resp *response =
178 (struct pldm_only_cc_resp *)msg->payload;
179 response->completion_code = completion_code;
180
181 return PLDM_SUCCESS;
182}
183
184int decode_set_date_time_resp(const struct pldm_msg *msg, size_t payload_length,
185 uint8_t *completion_code)
186{
187 if (msg == NULL || completion_code == NULL) {
188 return PLDM_ERROR_INVALID_DATA;
189 }
190
George Liu684a7162019-12-06 15:10:52 +0800191 *completion_code = msg->payload[0];
192 if (PLDM_SUCCESS != *completion_code) {
193 return PLDM_SUCCESS;
194 }
195
Xiaochao Ma39ae2a92019-11-12 20:30:34 +0800196 if (payload_length != sizeof(struct pldm_only_cc_resp)) {
197 return PLDM_ERROR_INVALID_LENGTH;
198 }
199
Xiaochao Ma39ae2a92019-11-12 20:30:34 +0800200 return PLDM_SUCCESS;
201}
202
Sampa Misrab37be312019-07-03 02:26:41 -0500203int encode_get_bios_table_resp(uint8_t instance_id, uint8_t completion_code,
204 uint32_t next_transfer_handle,
205 uint8_t transfer_flag, uint8_t *table_data,
206 size_t payload_length, struct pldm_msg *msg)
207{
208 struct pldm_header_info header = {0};
209 int rc = PLDM_SUCCESS;
210
211 if (msg == NULL) {
212 return PLDM_ERROR_INVALID_DATA;
213 }
214
215 struct pldm_get_bios_table_resp *response =
216 (struct pldm_get_bios_table_resp *)msg->payload;
217
218 response->completion_code = completion_code;
219 header.msg_type = PLDM_RESPONSE;
220 header.instance = instance_id;
221 header.pldm_type = PLDM_BIOS;
222 header.command = PLDM_GET_BIOS_TABLE;
223 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
224 return rc;
225 }
226
227 if (response->completion_code == PLDM_SUCCESS) {
228
229 response->next_transfer_handle = htole32(next_transfer_handle);
230 response->transfer_flag = transfer_flag;
231 if (table_data != NULL &&
232 payload_length > (sizeof(struct pldm_msg_hdr) +
233 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES)) {
234 memcpy(response->table_data, table_data,
235 payload_length -
236 (sizeof(struct pldm_msg_hdr) +
237 PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES));
238 }
239 }
240 return PLDM_SUCCESS;
241}
242
Sridevi Rameshd3d5fa82019-10-29 11:45:16 -0500243int encode_get_bios_table_req(uint8_t instance_id, uint32_t transfer_handle,
244 uint8_t transfer_op_flag, uint8_t table_type,
245 struct pldm_msg *msg)
246{
247 struct pldm_header_info header = {0};
248
249 if (msg == NULL) {
250 return PLDM_ERROR_INVALID_DATA;
251 }
252
253 header.msg_type = PLDM_REQUEST;
254 header.instance = instance_id;
255 header.pldm_type = PLDM_BIOS;
256 header.command = PLDM_GET_BIOS_TABLE;
257 pack_pldm_header(&header, &(msg->hdr));
258
259 struct pldm_get_bios_table_req *request =
260 (struct pldm_get_bios_table_req *)msg->payload;
261
262 request->transfer_handle = htole32(transfer_handle);
263 request->transfer_op_flag = transfer_op_flag;
264 request->table_type = table_type;
265 return PLDM_SUCCESS;
266}
267
Sampa Misrab37be312019-07-03 02:26:41 -0500268int decode_get_bios_table_req(const struct pldm_msg *msg, size_t payload_length,
269 uint32_t *transfer_handle,
270 uint8_t *transfer_op_flag, uint8_t *table_type)
271{
272 if (msg == NULL || transfer_op_flag == NULL || table_type == NULL ||
273 transfer_handle == NULL) {
274 return PLDM_ERROR_INVALID_DATA;
275 }
276
277 if (payload_length != PLDM_GET_BIOS_TABLE_REQ_BYTES) {
278 return PLDM_ERROR_INVALID_LENGTH;
279 }
280
281 struct pldm_get_bios_table_req *request =
282 (struct pldm_get_bios_table_req *)msg->payload;
283 *transfer_handle = le32toh(request->transfer_handle);
284 *transfer_op_flag = request->transfer_op_flag;
285 *table_type = request->table_type;
286
287 return PLDM_SUCCESS;
288}
Zahed Hossaind69af0b2019-07-30 01:33:31 -0500289
Sridevi Ramesh08efc7b2019-12-05 05:39:46 -0600290int decode_get_bios_table_resp(const struct pldm_msg *msg,
291 size_t payload_length, uint8_t *completion_code,
292 uint32_t *next_transfer_handle,
293 uint8_t *transfer_flag,
294 size_t *bios_table_offset)
295
296{
297 if (msg == NULL || transfer_flag == NULL ||
298 next_transfer_handle == NULL || completion_code == NULL) {
299 return PLDM_ERROR_INVALID_DATA;
300 }
301 if (payload_length <= PLDM_GET_BIOS_TABLE_MIN_RESP_BYTES) {
302 return PLDM_ERROR_INVALID_LENGTH;
303 }
304
305 struct pldm_get_bios_table_resp *response =
306 (struct pldm_get_bios_table_resp *)msg->payload;
307
308 *completion_code = response->completion_code;
309
310 if (PLDM_SUCCESS != *completion_code) {
311 return PLDM_SUCCESS;
312 }
313
314 *next_transfer_handle = le32toh(response->next_transfer_handle);
315 *transfer_flag = response->transfer_flag;
316
317 *bios_table_offset = sizeof(*completion_code) +
318 sizeof(*next_transfer_handle) +
319 sizeof(*transfer_flag);
320
321 return PLDM_SUCCESS;
322}
323
Adair Lica37ccb2020-04-24 14:32:58 +0800324int encode_get_bios_attribute_current_value_by_handle_req(
325 uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_op_flag,
326 uint16_t attribute_handle, struct pldm_msg *msg)
327{
328 struct pldm_header_info header = {0};
329
330 if (msg == NULL) {
331 return PLDM_ERROR_INVALID_DATA;
332 }
333
334 header.msg_type = PLDM_REQUEST;
335 header.instance = instance_id;
336 header.pldm_type = PLDM_BIOS;
337 header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
338 pack_pldm_header(&header, &(msg->hdr));
339
340 struct pldm_get_bios_attribute_current_value_by_handle_req *request =
341 (struct pldm_get_bios_attribute_current_value_by_handle_req *)
342 msg->payload;
343
344 request->transfer_handle = htole32(transfer_handle);
345 request->transfer_op_flag = transfer_op_flag;
346 request->attribute_handle = htole16(attribute_handle);
347 return PLDM_SUCCESS;
348}
349
350int decode_get_bios_attribute_current_value_by_handle_resp(
351 const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
352 uint32_t *next_transfer_handle, uint8_t *transfer_flag,
353 struct variable_field *attribute_data)
354{
355 if (msg == NULL || transfer_flag == NULL ||
356 next_transfer_handle == NULL || completion_code == NULL) {
357 return PLDM_ERROR_INVALID_DATA;
358 }
359
360 struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
361 (struct pldm_get_bios_attribute_current_value_by_handle_resp *)
362 msg->payload;
363
364 *completion_code = response->completion_code;
365
366 if (PLDM_SUCCESS != *completion_code) {
367 return PLDM_SUCCESS;
368 }
369
370 if (payload_length <=
371 PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_MIN_RESP_BYTES) {
372 return PLDM_ERROR_INVALID_LENGTH;
373 }
374
375 *next_transfer_handle = le32toh(response->next_transfer_handle);
376 *transfer_flag = response->transfer_flag;
377
378 attribute_data->ptr = response->attribute_data;
379 attribute_data->length = payload_length - sizeof(*response) + 1;
380
381 return PLDM_SUCCESS;
382}
383
Zahed Hossaind69af0b2019-07-30 01:33:31 -0500384int decode_get_bios_attribute_current_value_by_handle_req(
385 const struct pldm_msg *msg, size_t payload_length,
386 uint32_t *transfer_handle, uint8_t *transfer_op_flag,
387 uint16_t *attribute_handle)
388{
389 if (msg == NULL || transfer_handle == NULL ||
390 transfer_op_flag == NULL || attribute_handle == NULL) {
391 return PLDM_ERROR_INVALID_DATA;
392 }
393
394 if (payload_length != PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES) {
395 return PLDM_ERROR_INVALID_LENGTH;
396 }
397
398 struct pldm_get_bios_attribute_current_value_by_handle_req *request =
399 (struct pldm_get_bios_attribute_current_value_by_handle_req *)
400 msg->payload;
401 *transfer_handle = le32toh(request->transfer_handle);
402 *transfer_op_flag = request->transfer_op_flag;
403 *attribute_handle = le16toh(request->attribute_handle);
404
405 return PLDM_SUCCESS;
406}
407
408int encode_get_bios_current_value_by_handle_resp(
409 uint8_t instance_id, uint8_t completion_code, uint32_t next_transfer_handle,
410 uint8_t transfer_flag, const uint8_t *attribute_data,
411 size_t attribute_length, struct pldm_msg *msg)
412{
413 struct pldm_header_info header = {0};
414 int rc = PLDM_SUCCESS;
415
416 if (msg == NULL || attribute_data == NULL) {
417 return PLDM_ERROR_INVALID_DATA;
418 }
419
420 struct pldm_get_bios_attribute_current_value_by_handle_resp *response =
421 (struct pldm_get_bios_attribute_current_value_by_handle_resp *)
422 msg->payload;
423
424 response->completion_code = completion_code;
425 header.msg_type = PLDM_RESPONSE;
426 header.instance = instance_id;
427 header.pldm_type = PLDM_BIOS;
428 header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
429 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
430 return rc;
431 }
432 if (response->completion_code == PLDM_SUCCESS) {
433
434 response->next_transfer_handle = htole32(next_transfer_handle);
435 response->transfer_flag = transfer_flag;
436 if (attribute_data != NULL) {
437 memcpy(response->attribute_data, attribute_data,
438 attribute_length);
439 }
440 }
441 return PLDM_SUCCESS;
442}
John Wang4d844792019-08-15 15:51:40 +0800443int encode_set_bios_attribute_current_value_req(
444 uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_flag,
445 const uint8_t *attribute_data, size_t attribute_length,
446 struct pldm_msg *msg, size_t payload_lenth)
447{
448 if (msg == NULL || attribute_data == NULL) {
449 return PLDM_ERROR_INVALID_DATA;
450 }
451 if (PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES + attribute_length !=
452 payload_lenth) {
453 return PLDM_ERROR_INVALID_LENGTH;
454 }
455 struct pldm_header_info header = {0};
456 header.instance = instance_id;
457 header.msg_type = PLDM_REQUEST;
458 header.pldm_type = PLDM_BIOS;
459 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
460 pack_pldm_header(&header, &msg->hdr);
461
462 struct pldm_set_bios_attribute_current_value_req *request =
463 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
464 request->transfer_handle = htole32(transfer_handle);
465 request->transfer_flag = transfer_flag;
466 memcpy(request->attribute_data, attribute_data, attribute_length);
467
468 return PLDM_SUCCESS;
469}
470
471int decode_set_bios_attribute_current_value_resp(const struct pldm_msg *msg,
472 size_t payload_length,
473 uint8_t *completion_code,
474 uint32_t *next_transfer_handle)
475{
476 if (msg == NULL || completion_code == NULL ||
477 next_transfer_handle == NULL) {
478 return PLDM_ERROR_INVALID_DATA;
479 }
George Liu684a7162019-12-06 15:10:52 +0800480
481 *completion_code = msg->payload[0];
482 if (PLDM_SUCCESS != *completion_code) {
483 return PLDM_SUCCESS;
484 }
485
John Wang4d844792019-08-15 15:51:40 +0800486 if (payload_length != PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES) {
487 return PLDM_ERROR_INVALID_LENGTH;
488 }
489
490 struct pldm_set_bios_attribute_current_value_resp *response =
491 (struct pldm_set_bios_attribute_current_value_resp *)msg->payload;
492
John Wang4d844792019-08-15 15:51:40 +0800493 *next_transfer_handle = le32toh(response->next_transfer_handle);
494
495 return PLDM_SUCCESS;
496}
497
John Wang08c05952019-12-20 15:40:39 +0800498int decode_set_bios_attribute_current_value_req(
499 const struct pldm_msg *msg, size_t payload_length,
500 uint32_t *transfer_handle, uint8_t *transfer_flag,
501 struct variable_field *attribute)
John Wang4d844792019-08-15 15:51:40 +0800502{
503 if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
John Wang08c05952019-12-20 15:40:39 +0800504 attribute == NULL) {
John Wang4d844792019-08-15 15:51:40 +0800505 return PLDM_ERROR_INVALID_DATA;
506 }
507 if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
508 return PLDM_ERROR_INVALID_LENGTH;
509 }
510
511 struct pldm_set_bios_attribute_current_value_req *request =
512 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
513 *transfer_handle = le32toh(request->transfer_handle);
514 *transfer_flag = request->transfer_flag;
John Wang08c05952019-12-20 15:40:39 +0800515 attribute->length =
John Wang4d844792019-08-15 15:51:40 +0800516 payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES;
John Wang08c05952019-12-20 15:40:39 +0800517 attribute->ptr = request->attribute_data;
John Wang4d844792019-08-15 15:51:40 +0800518 return PLDM_SUCCESS;
519}
520
521int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
522 uint8_t completion_code,
523 uint32_t next_transfer_handle,
524 struct pldm_msg *msg)
525{
526 if (msg == NULL) {
527 return PLDM_ERROR_INVALID_DATA;
528 }
529 struct pldm_header_info header = {0};
530 header.instance = instance_id;
531 header.msg_type = PLDM_RESPONSE;
532 header.pldm_type = PLDM_BIOS;
533 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
534
535 int rc = pack_pldm_header(&header, &msg->hdr);
536 if (rc != PLDM_SUCCESS) {
537 return rc;
538 }
539
540 struct pldm_set_bios_attribute_current_value_resp *response =
541 (struct pldm_set_bios_attribute_current_value_resp *)msg->payload;
542 response->completion_code = completion_code;
543 response->next_transfer_handle = htole32(next_transfer_handle);
544
545 return PLDM_SUCCESS;
546}