xref: /aosp_15_r20/external/coreboot/src/commonlib/bsd/elog.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 
3 #include <commonlib/bsd/bcd.h>
4 #include <commonlib/bsd/elog.h>
5 #include <stddef.h>
6 
7 /*
8  * verify and validate if header is a valid coreboot Event Log header.
9  * return CB_ERR if invalid, otherwise CB_SUCCESS.
10  */
elog_verify_header(const struct elog_header * header)11 enum cb_err elog_verify_header(const struct elog_header *header)
12 {
13 	if (header == NULL)
14 		return CB_ERR;
15 
16 	if (header->magic != ELOG_SIGNATURE)
17 		return CB_ERR;
18 
19 	if (header->version != ELOG_VERSION)
20 		return CB_ERR;
21 
22 	if (header->header_size != sizeof(*header))
23 		return CB_ERR;
24 
25 	return CB_SUCCESS;
26 }
27 
28 /*
29  * return the next elog event.
30  * return NULL if event is invalid.
31  */
elog_get_next_event(const struct event_header * event)32 const struct event_header *elog_get_next_event(const struct event_header *event)
33 {
34 	if (!event)
35 		return NULL;
36 
37 	/* Point to next event */
38 	return (const struct event_header *)((const void *)(event) + event->length);
39 }
40 
41 /* return the data associated to the event_header. */
event_get_data(const struct event_header * event)42 const void *event_get_data(const struct event_header *event)
43 {
44 	/*
45 	 * Pointing to the next event returns the data, since data is the first
46 	 * field right after the header.
47 	 */
48 	return (const void *)(&event[1]);
49 }
50 
51 /* Populate timestamp in event header with given time. */
elog_fill_timestamp(struct event_header * event,uint8_t sec,uint8_t min,uint8_t hour,uint8_t mday,uint8_t mon,uint16_t year)52 void elog_fill_timestamp(struct event_header *event, uint8_t sec, uint8_t min,
53 			 uint8_t hour, uint8_t mday, uint8_t mon, uint16_t year)
54 {
55 	event->second = bin2bcd(sec);
56 	event->minute = bin2bcd(min);
57 	event->hour = bin2bcd(hour);
58 	event->day = bin2bcd(mday);
59 	event->month = bin2bcd(mon);
60 	event->year = bin2bcd(year % 100);
61 
62 	/* Basic check of expected ranges. */
63 	if (event->month > 0x12 || event->day > 0x31 || event->hour > 0x23 ||
64 	    event->minute > 0x59 || event->second > 0x59) {
65 		event->year   = 0;
66 		event->month  = 0;
67 		event->day    = 0;
68 		event->hour   = 0;
69 		event->minute = 0;
70 		event->second = 0;
71 	}
72 }
73 
elog_update_checksum(struct event_header * event,uint8_t checksum)74 void elog_update_checksum(struct event_header *event, uint8_t checksum)
75 {
76 	uint8_t *event_data = (uint8_t *)event;
77 	event_data[event->length - 1] = checksum;
78 }
79 
elog_checksum_event(const struct event_header * event)80 uint8_t elog_checksum_event(const struct event_header *event)
81 {
82 	uint8_t index, checksum = 0;
83 	const uint8_t *data = (const uint8_t *)event;
84 
85 	for (index = 0; index < event->length; index++)
86 		checksum += data[index];
87 	return checksum;
88 }
89