blob: 958b7c8ec6aabb446602a87c531507d80c78e457 [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
Zahed Hossaind69af0b2019-07-30 01:33:31 -0500324int decode_get_bios_attribute_current_value_by_handle_req(
325 const struct pldm_msg *msg, size_t payload_length,
326 uint32_t *transfer_handle, uint8_t *transfer_op_flag,
327 uint16_t *attribute_handle)
328{
329 if (msg == NULL || transfer_handle == NULL ||
330 transfer_op_flag == NULL || attribute_handle == NULL) {
331 return PLDM_ERROR_INVALID_DATA;
332 }
333
334 if (payload_length != PLDM_GET_BIOS_ATTR_CURR_VAL_BY_HANDLE_REQ_BYTES) {
335 return PLDM_ERROR_INVALID_LENGTH;
336 }
337
338 struct pldm_get_bios_attribute_current_value_by_handle_req *request =
339 (struct pldm_get_bios_attribute_current_value_by_handle_req *)
340 msg->payload;
341 *transfer_handle = le32toh(request->transfer_handle);
342 *transfer_op_flag = request->transfer_op_flag;
343 *attribute_handle = le16toh(request->attribute_handle);
344
345 return PLDM_SUCCESS;
346}
347
348int encode_get_bios_current_value_by_handle_resp(
349 uint8_t instance_id, uint8_t completion_code, uint32_t next_transfer_handle,
350 uint8_t transfer_flag, const uint8_t *attribute_data,
351 size_t attribute_length, struct pldm_msg *msg)
352{
353 struct pldm_header_info header = {0};
354 int rc = PLDM_SUCCESS;
355
356 if (msg == NULL || attribute_data == 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 response->completion_code = completion_code;
365 header.msg_type = PLDM_RESPONSE;
366 header.instance = instance_id;
367 header.pldm_type = PLDM_BIOS;
368 header.command = PLDM_GET_BIOS_ATTRIBUTE_CURRENT_VALUE_BY_HANDLE;
369 if ((rc = pack_pldm_header(&header, &(msg->hdr))) > PLDM_SUCCESS) {
370 return rc;
371 }
372 if (response->completion_code == PLDM_SUCCESS) {
373
374 response->next_transfer_handle = htole32(next_transfer_handle);
375 response->transfer_flag = transfer_flag;
376 if (attribute_data != NULL) {
377 memcpy(response->attribute_data, attribute_data,
378 attribute_length);
379 }
380 }
381 return PLDM_SUCCESS;
382}
John Wang4d844792019-08-15 15:51:40 +0800383int encode_set_bios_attribute_current_value_req(
384 uint8_t instance_id, uint32_t transfer_handle, uint8_t transfer_flag,
385 const uint8_t *attribute_data, size_t attribute_length,
386 struct pldm_msg *msg, size_t payload_lenth)
387{
388 if (msg == NULL || attribute_data == NULL) {
389 return PLDM_ERROR_INVALID_DATA;
390 }
391 if (PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES + attribute_length !=
392 payload_lenth) {
393 return PLDM_ERROR_INVALID_LENGTH;
394 }
395 struct pldm_header_info header = {0};
396 header.instance = instance_id;
397 header.msg_type = PLDM_REQUEST;
398 header.pldm_type = PLDM_BIOS;
399 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
400 pack_pldm_header(&header, &msg->hdr);
401
402 struct pldm_set_bios_attribute_current_value_req *request =
403 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
404 request->transfer_handle = htole32(transfer_handle);
405 request->transfer_flag = transfer_flag;
406 memcpy(request->attribute_data, attribute_data, attribute_length);
407
408 return PLDM_SUCCESS;
409}
410
411int decode_set_bios_attribute_current_value_resp(const struct pldm_msg *msg,
412 size_t payload_length,
413 uint8_t *completion_code,
414 uint32_t *next_transfer_handle)
415{
416 if (msg == NULL || completion_code == NULL ||
417 next_transfer_handle == NULL) {
418 return PLDM_ERROR_INVALID_DATA;
419 }
George Liu684a7162019-12-06 15:10:52 +0800420
421 *completion_code = msg->payload[0];
422 if (PLDM_SUCCESS != *completion_code) {
423 return PLDM_SUCCESS;
424 }
425
John Wang4d844792019-08-15 15:51:40 +0800426 if (payload_length != PLDM_SET_BIOS_ATTR_CURR_VAL_RESP_BYTES) {
427 return PLDM_ERROR_INVALID_LENGTH;
428 }
429
430 struct pldm_set_bios_attribute_current_value_resp *response =
431 (struct pldm_set_bios_attribute_current_value_resp *)msg->payload;
432
John Wang4d844792019-08-15 15:51:40 +0800433 *next_transfer_handle = le32toh(response->next_transfer_handle);
434
435 return PLDM_SUCCESS;
436}
437
John Wang08c05952019-12-20 15:40:39 +0800438int decode_set_bios_attribute_current_value_req(
439 const struct pldm_msg *msg, size_t payload_length,
440 uint32_t *transfer_handle, uint8_t *transfer_flag,
441 struct variable_field *attribute)
John Wang4d844792019-08-15 15:51:40 +0800442{
443 if (msg == NULL || transfer_handle == NULL || transfer_flag == NULL ||
John Wang08c05952019-12-20 15:40:39 +0800444 attribute == NULL) {
John Wang4d844792019-08-15 15:51:40 +0800445 return PLDM_ERROR_INVALID_DATA;
446 }
447 if (payload_length < PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES) {
448 return PLDM_ERROR_INVALID_LENGTH;
449 }
450
451 struct pldm_set_bios_attribute_current_value_req *request =
452 (struct pldm_set_bios_attribute_current_value_req *)msg->payload;
453 *transfer_handle = le32toh(request->transfer_handle);
454 *transfer_flag = request->transfer_flag;
John Wang08c05952019-12-20 15:40:39 +0800455 attribute->length =
John Wang4d844792019-08-15 15:51:40 +0800456 payload_length - PLDM_SET_BIOS_ATTR_CURR_VAL_MIN_REQ_BYTES;
John Wang08c05952019-12-20 15:40:39 +0800457 attribute->ptr = request->attribute_data;
John Wang4d844792019-08-15 15:51:40 +0800458 return PLDM_SUCCESS;
459}
460
461int encode_set_bios_attribute_current_value_resp(uint8_t instance_id,
462 uint8_t completion_code,
463 uint32_t next_transfer_handle,
464 struct pldm_msg *msg)
465{
466 if (msg == NULL) {
467 return PLDM_ERROR_INVALID_DATA;
468 }
469 struct pldm_header_info header = {0};
470 header.instance = instance_id;
471 header.msg_type = PLDM_RESPONSE;
472 header.pldm_type = PLDM_BIOS;
473 header.command = PLDM_SET_BIOS_ATTRIBUTE_CURRENT_VALUE;
474
475 int rc = pack_pldm_header(&header, &msg->hdr);
476 if (rc != PLDM_SUCCESS) {
477 return rc;
478 }
479
480 struct pldm_set_bios_attribute_current_value_resp *response =
481 (struct pldm_set_bios_attribute_current_value_resp *)msg->payload;
482 response->completion_code = completion_code;
483 response->next_transfer_handle = htole32(next_transfer_handle);
484
485 return PLDM_SUCCESS;
486}