coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
elog.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <boot_device.h>
5 #include <bootstate.h>
6 #include <cbmem.h>
7 #include <commonlib/bsd/bcd.h>
8 #include <commonlib/bsd/elog.h>
9 #include <commonlib/region.h>
10 #include <console/console.h>
11 #include <elog.h>
12 #include <fmap.h>
13 #include <lib.h>
14 #include <post.h>
15 #include <rtc.h>
16 #include <smbios.h>
17 #include <stdint.h>
18 #include <string.h>
19 #include <timestamp.h>
20 
21 #define ELOG_MIN_AVAILABLE_ENTRIES 2 /* Shrink when this many can't fit */
22 #define ELOG_SHRINK_PERCENTAGE 25 /* Percent of total area to remove */
23 
24 #if CONFIG(ELOG_DEBUG)
25 #define elog_debug(STR...) printk(BIOS_DEBUG, STR)
26 #else
27 #define elog_debug(STR...)
28 #endif
29 
30 #define NV_NEEDS_ERASE (~(size_t)0)
35 };
36 
37 struct elog_state {
40 
41  /*
42  * The non-volatile storage chases the mirrored copy. When nv_last_write
43  * is less than the mirrored last write the non-volatile storage needs
44  * to be updated.
45  */
47  size_t nv_last_write;
48 
49  struct region_device nv_dev;
50  /* Device that mirrors the eventlog in memory. */
52 
54 };
55 
56 static struct elog_state elog_state;
57 
58 #define ELOG_SIZE (4 * KiB)
60 
61 static inline struct region_device *mirror_dev_get(void)
62 {
63  return &elog_state.mirror_dev;
64 }
65 
66 static size_t elog_events_start(void)
67 {
68  /* Events are added directly after the header. */
69  return sizeof(struct elog_header);
70 }
71 
72 static size_t elog_events_total_space(void)
73 {
75 }
76 
77 static struct event_header *elog_get_event_buffer(size_t offset, size_t size)
78 {
79  return rdev_mmap(mirror_dev_get(), offset, size);
80 }
81 
82 static struct event_header *elog_get_next_event_buffer(size_t size)
83 {
84  elog_debug("ELOG: new event at offset 0x%zx\n",
87 }
88 
89 static void elog_put_event_buffer(struct event_header *event)
90 {
91  rdev_munmap(mirror_dev_get(), event);
92 }
93 
94 static size_t elog_mirror_reset_last_write(void)
95 {
96  /* Return previous write value. */
97  size_t prev = elog_state.mirror_last_write;
98 
100  return prev;
101 }
102 
103 static void elog_mirror_increment_last_write(size_t size)
104 {
106 }
107 
108 static void elog_nv_reset_last_write(void)
109 {
111 }
112 
113 static void elog_nv_increment_last_write(size_t size)
114 {
115  elog_state.nv_last_write += size;
116 }
117 
119 {
120  /* If last write is 0 it means it is already erased. */
121  if (elog_state.nv_last_write != 0)
123 }
124 
125 static bool elog_should_shrink(void)
126 {
128 }
129 
130 static bool elog_nv_needs_erase(void)
131 {
133 }
134 
135 static bool elog_nv_needs_update(void)
136 {
138 }
139 
140 static size_t elog_nv_region_to_update(size_t *offset)
141 {
144 }
145 
146 /*
147  * When parsing state from the NV one needs to adjust both the NV and mirror
148  * write state. Therefore, provide helper functions which adjust both
149  * at the same time.
150  */
152 {
155 }
156 
157 static void elog_tandem_increment_last_write(size_t size)
158 {
161 }
162 
163 static void elog_debug_dump_buffer(const char *msg)
164 {
165  struct region_device *rdev;
166  void *buffer;
167 
168  if (!CONFIG(ELOG_DEBUG))
169  return;
170 
171  elog_debug(msg);
172 
173  rdev = mirror_dev_get();
174 
176 
177  if (buffer == NULL)
178  return;
179 
181 
183 }
184 
185 /*
186  * Check if mirrored buffer is filled with ELOG_TYPE_EOL byte from the
187  * provided offset to the end of the mirrored buffer.
188  */
189 static int elog_is_buffer_clear(size_t offset)
190 {
191  size_t i;
192  const struct region_device *rdev = mirror_dev_get();
193  size_t size = region_device_sz(rdev) - offset;
194  uint8_t *buffer = rdev_mmap(rdev, offset, size);
195  int ret = 1;
196 
197  elog_debug("%s(offset=%zu size=%zu)\n", __func__, offset, size);
198 
199  if (buffer == NULL)
200  return 0;
201 
202  for (i = 0; i < size; i++) {
203  if (buffer[i] != ELOG_TYPE_EOL) {
204  ret = 0;
205  break;
206  }
207  }
209  return ret;
210 }
211 
212 /*
213  * Verify if the mirrored elog structure is valid.
214  * Returns 1 if the header is valid, 0 otherwise
215  */
216 static int elog_is_header_valid(void)
217 {
218  struct elog_header *header;
219 
220  elog_debug("%s()\n", __func__);
221 
222  header = rdev_mmap(mirror_dev_get(), 0, sizeof(*header));
223 
225  printk(BIOS_ERR, "ELOG: failed to verify header.\n");
226  return 0;
227  }
228  return 1;
229 }
230 
231 /*
232  * Validate the event header and data.
233  */
234 static size_t elog_is_event_valid(size_t offset)
235 {
237  struct event_header *event;
238  uint8_t len;
239  const size_t len_offset = offsetof(struct event_header, length);
240  const size_t size = sizeof(len);
241 
242  /* Read and validate length. */
243  if (rdev_readat(mirror_dev_get(), &len, offset + len_offset, size) < 0)
244  return 0;
245 
246  /* Event length must be at least header size + checksum */
247  if (len < (sizeof(*event) + sizeof(checksum)))
248  return 0;
249 
250  if (len > ELOG_MAX_EVENT_SIZE)
251  return 0;
252 
253  event = elog_get_event_buffer(offset, len);
254  if (!event)
255  return 0;
256 
257  /* If event checksum is invalid the area is corrupt */
258  checksum = elog_checksum_event(event);
259  elog_put_event_buffer(event);
260 
261  if (checksum != 0)
262  return 0;
263 
264  /* Event is valid */
265  return len;
266 }
267 
268 /*
269  * Write 'size' bytes of data from provided 'offset' in the mirrored elog to
270  * the flash backing store. This will not erase the flash and it assumes the
271  * flash area has been erased appropriately.
272  */
273 static void elog_nv_write(size_t offset, size_t size)
274 {
275  void *address;
276  const struct region_device *rdev = mirror_dev_get();
277  if (!size)
278  return;
279 
280  address = rdev_mmap(rdev, offset, size);
281 
282  elog_debug("%s(address=%p offset=0x%08zx size=%zu)\n", __func__,
283  address, offset, size);
284 
285  if (address == NULL)
286  return;
287 
288  /* Write the data to flash */
289  if (rdev_writeat(&elog_state.nv_dev, address, offset, size) != size)
290  printk(BIOS_ERR, "ELOG: NV Write failed at 0x%zx, size 0x%zx\n",
291  offset, size);
292 
294 }
295 
296 /*
297  * Erase the first block specified in the address.
298  * Only handles flash area within a single flash block.
299  */
300 static void elog_nv_erase(void)
301 {
302  size_t size = region_device_sz(&elog_state.nv_dev);
303  elog_debug("%s()\n", __func__);
304 
305  /* Erase the sectors in this region */
306  if (rdev_eraseat(&elog_state.nv_dev, 0, size) != size)
307  printk(BIOS_ERR, "ELOG: erase failure.\n");
308 }
309 
310 /*
311  * Scan the event area and validate each entry and update the ELOG state.
312  */
314 {
315  size_t offset = elog_events_start();
316 
317  elog_debug("%s()\n", __func__);
318 
319  /* Go through each event and validate it */
320  while (1) {
321  uint8_t type;
322  const size_t type_offset = offsetof(struct event_header, type);
323  size_t len;
324  const size_t size = sizeof(type);
325 
327  offset + type_offset, size) < 0) {
328  return -1;
329  }
330 
331  /* The end of the event marker has been found */
332  if (type == ELOG_TYPE_EOL)
333  break;
334 
335  /* Validate the event */
337 
338  if (!len) {
339  printk(BIOS_ERR, "ELOG: Invalid event @ offset 0x%zx\n",
340  offset);
341  return -1;
342  }
343 
344  /* Move to the next event */
346  offset += len;
347  }
348 
349  /* Ensure the remaining buffer is empty */
351  printk(BIOS_ERR, "ELOG: buffer not cleared from 0x%zx\n",
352  offset);
353  return -1;
354  }
355 
356  return 0;
357 }
358 
359 static int elog_scan_flash(void)
360 {
361  elog_debug("%s()\n", __func__);
362  void *mirror_buffer;
363  const struct region_device *rdev = mirror_dev_get();
364 
365  size_t size = region_device_sz(&elog_state.nv_dev);
366 
367  /* Fill memory buffer by reading from SPI */
368  mirror_buffer = rdev_mmap_full(rdev);
369  if (rdev_readat(&elog_state.nv_dev, mirror_buffer, 0, size) != size) {
370  rdev_munmap(rdev, mirror_buffer);
371  printk(BIOS_ERR, "ELOG: NV read failure.\n");
372  return -1;
373  }
374  rdev_munmap(rdev, mirror_buffer);
375 
376  /* No writes have been done yet. */
378 
379  /* Check if the area is empty or not */
380  if (elog_is_buffer_clear(0)) {
381  printk(BIOS_ERR, "ELOG: NV Buffer Cleared.\n");
382  return -1;
383  }
384 
385  /* Indicate that header possibly written. */
387 
388  /* Validate the header */
389  if (!elog_is_header_valid()) {
390  printk(BIOS_ERR, "ELOG: NV Buffer Invalid.\n");
391  return -1;
392  }
393 
395 }
396 
398 {
399  static const struct elog_header header = {
401  .version = ELOG_VERSION,
402  .header_size = sizeof(struct elog_header),
403  .reserved = {
404  [0] = ELOG_TYPE_EOL,
405  [1] = ELOG_TYPE_EOL,
406  },
407  };
408 
409  rdev_writeat(mirror_dev_get(), &header, 0, sizeof(header));
411 }
412 
413 static void elog_move_events_to_front(size_t offset, size_t size)
414 {
415  void *src;
416  void *dest;
417  size_t start_offset = elog_events_start();
418  const struct region_device *rdev = mirror_dev_get();
419 
420  src = rdev_mmap(rdev, offset, size);
421  dest = rdev_mmap(rdev, start_offset, size);
422 
423  if (src == NULL || dest == NULL) {
424  printk(BIOS_ERR, "ELOG: failure moving events!\n");
425  rdev_munmap(rdev, dest);
426  rdev_munmap(rdev, src);
427  return;
428  }
429 
430  /* Move the events to the front. */
431  memmove(dest, src, size);
432  rdev_munmap(rdev, dest);
433  rdev_munmap(rdev, src);
434 
435  /* Mark EOL for previously used buffer until the end. */
436  offset = start_offset + size;
437  size = region_device_sz(rdev) - offset;
438  dest = rdev_mmap(rdev, offset, size);
439  if (dest == NULL) {
440  printk(BIOS_ERR, "ELOG: failure filling EOL!\n");
441  return;
442  }
443  memset(dest, ELOG_TYPE_EOL, size);
444  rdev_munmap(rdev, dest);
445 }
446 
447 /* Perform the shrink and move events returning the size of bytes shrunk. */
448 static size_t elog_do_shrink(size_t requested_size, size_t last_write)
449 {
450  const struct region_device *rdev = mirror_dev_get();
451  size_t offset = elog_events_start();
452  size_t remaining_size;
453 
454  while (1) {
455  const size_t type_offset = offsetof(struct event_header, type);
456  const size_t len_offset = offsetof(struct event_header, length);
457  const size_t size = sizeof(uint8_t);
458  uint8_t type;
459  uint8_t len;
460 
461  /* Next event has exceeded constraints */
462  if (offset > requested_size)
463  break;
464 
465  if (rdev_readat(rdev, &type, offset + type_offset, size) < 0)
466  break;
467 
468  /* Reached the end of the area */
469  if (type == ELOG_TYPE_EOL)
470  break;
471 
472  if (rdev_readat(rdev, &len, offset + len_offset, size) < 0)
473  break;
474 
475  offset += len;
476  }
477 
478  /*
479  * Move the events and update the last write. The last write before
480  * shrinking was captured prior to resetting the counter to determine
481  * actual size we're keeping.
482  */
483  remaining_size = last_write - offset;
484  elog_debug("ELOG: shrinking offset: 0x%zx remaining_size: 0x%zx\n",
485  offset, remaining_size);
486  elog_move_events_to_front(offset, remaining_size);
487  elog_mirror_increment_last_write(remaining_size);
488 
489  /* Return the amount of data removed. */
490  return offset - elog_events_start();
491 }
492 
493 /*
494  * Shrink the log, deleting old entries and moving the
495  * remaining ones to the front of the log.
496  */
497 static int elog_shrink_by_size(size_t requested_size)
498 {
499  size_t shrunk_size;
500  size_t captured_last_write;
501  size_t total_event_space = elog_events_total_space();
502 
503  elog_debug("%s()\n", __func__);
504 
505  /* Indicate possible erase required. */
507 
508  /* Capture the last write to determine data size in buffer to shrink. */
509  captured_last_write = elog_mirror_reset_last_write();
510 
511  /* Prepare new header. */
513 
514  /* Determine if any actual shrinking is required. */
515  if (requested_size >= total_event_space)
516  shrunk_size = total_event_space;
517  else
518  shrunk_size = elog_do_shrink(requested_size,
519  captured_last_write);
520 
521  /* Add clear event */
522  return elog_add_event_word(ELOG_TYPE_LOG_CLEAR, shrunk_size);
523 }
524 
525 static int elog_prepare_empty(void)
526 {
527  elog_debug("%s()\n", __func__);
529 }
530 
531 static int elog_shrink(void)
532 {
533  if (elog_should_shrink())
535  return 0;
536 }
537 
538 /*
539  * Convert a flash offset into a memory mapped flash address
540  */
541 static inline u8 *elog_flash_offset_to_address(void)
542 {
543  /* Only support memory-mapped devices. */
544  if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED))
545  return NULL;
546 
548  return NULL;
549 
550  /* Get a view into the read-only boot device. */
551  return rdev_mmap(boot_device_ro(),
554 }
555 
556 /*
557  * Fill out SMBIOS Type 15 table entry so the
558  * event log can be discovered at runtime.
559  */
560 int elog_smbios_write_type15(unsigned long *current, int handle)
561 {
562  uintptr_t log_address;
563 
564  size_t elog_size = region_device_sz(&elog_state.nv_dev);
565 
566  if (CONFIG(ELOG_CBMEM)) {
567  /* Save event log buffer into CBMEM for the OS to read */
568  void *cbmem = cbmem_add(CBMEM_ID_ELOG, elog_size);
569  if (cbmem)
570  rdev_readat(mirror_dev_get(), cbmem, 0, elog_size);
571  log_address = (uintptr_t)cbmem;
572  } else {
573  log_address = (uintptr_t)elog_flash_offset_to_address();
574  }
575 
576  if (!log_address) {
577  printk(BIOS_WARNING, "SMBIOS type 15 log address invalid.\n");
578  return 0;
579  }
580 
581  struct smbios_type15 *t = smbios_carve_table(*current, SMBIOS_EVENT_LOG,
582  sizeof(*t), handle);
583 
584  t->area_length = elog_size - 1;
585  t->header_offset = 0;
586  t->data_offset = sizeof(struct elog_header);
589  t->change_token = 0;
590  t->address = log_address;
592  t->log_type_descriptors = 0;
594 
595  const int len = smbios_full_table_len(&t->header, t->eos);
596  *current += len;
597  return len;
598 }
599 
600 /*
601  * Clear the entire event log
602  */
603 int elog_clear(void)
604 {
605  elog_debug("%s()\n", __func__);
606 
607  /* Make sure ELOG structures are initialized */
608  if (elog_init() < 0)
609  return -1;
610 
611  return elog_prepare_empty();
612 }
613 
614 static int elog_find_flash(void)
615 {
616  size_t total_size;
617  size_t reserved_space = ELOG_MIN_AVAILABLE_ENTRIES * ELOG_MAX_EVENT_SIZE;
618  struct region_device *rdev = &elog_state.nv_dev;
619 
620  elog_debug("%s()\n", __func__);
621 
622  /* Find the ELOG base and size in FMAP */
624  printk(BIOS_WARNING, "ELOG: Unable to find RW_ELOG in FMAP\n");
625  return -1;
626  }
627 
629  printk(BIOS_WARNING, "ELOG: Needs a minimum size of %dKiB: %zu\n",
631  return -1;
632  }
633 
634  printk(BIOS_INFO, "ELOG: NV offset 0x%zx size 0x%zx\n",
636 
637  /* Keep 4KiB max size until large malloc()s have been fixed. */
638  total_size = MIN(ELOG_SIZE, region_device_sz(rdev));
639  rdev_chain(rdev, rdev, 0, total_size);
640 
641  elog_state.full_threshold = total_size - reserved_space;
642  elog_state.shrink_size = total_size * ELOG_SHRINK_PERCENTAGE / 100;
643 
644  if (reserved_space > elog_state.shrink_size) {
645  printk(BIOS_ERR, "ELOG: SHRINK_PERCENTAGE too small\n");
646  return -1;
647  }
648 
649  return 0;
650 }
651 
652 static int elog_sync_to_nv(void)
653 {
654  size_t offset;
655  size_t size;
656  bool erase_needed;
657  /* Determine if any updates are required. */
658  if (!elog_nv_needs_update())
659  return 0;
660 
661  erase_needed = elog_nv_needs_erase();
662 
663  /* Erase if necessary. */
664  if (erase_needed) {
665  elog_nv_erase();
667  }
668 
670 
671  elog_nv_write(offset, size);
673 
674  /*
675  * If erase wasn't performed then don't rescan. Assume the appended
676  * write was successful.
677  */
678  if (!erase_needed)
679  return 0;
680 
681  elog_debug_dump_buffer("ELOG: in-memory mirror:\n");
682 
683  /* Mark broken if the scan failed after a sync. */
684  if (elog_scan_flash() < 0) {
685  printk(BIOS_ERR, "ELOG: Sync back from NV storage failed.\n");
686  elog_debug_dump_buffer("ELOG: Buffer from NV:\n");
688  return -1;
689  }
690 
691  return 0;
692 }
693 
694 /*
695  * Do not log boot count events in S3 resume or SMM.
696  */
697 static bool elog_do_add_boot_count(void)
698 {
699  if (ENV_SMM)
700  return false;
701 
702  return !acpi_is_wakeup_s3();
703 }
704 
705 /* Check and log POST codes from previous boot */
706 static void log_last_boot_post(void)
707 {
708 #if ENV_X86
709  u8 code;
710  u32 extra;
711 
712  if (!CONFIG(CMOS_POST))
713  return;
714 
715  if (cmos_post_previous_boot(&code, &extra) == 0)
716  return;
717 
718  printk(BIOS_WARNING, "POST: Unexpected post code/extra "
719  "in previous boot: 0x%02x/0x%04x\n", code, extra);
720 
722  if (extra)
724 #endif
725 }
726 
727 static void elog_add_boot_count(void)
728 {
729  if (elog_do_add_boot_count()) {
731 
733  }
734 }
735 
736 /*
737  * Event log main entry point
738  */
739 int elog_init(void)
740 {
741  void *mirror_buffer;
742  size_t elog_size;
743  switch (elog_state.elog_initialized) {
744  case ELOG_UNINITIALIZED:
745  break;
746  case ELOG_INITIALIZED:
747  return 0;
748  case ELOG_BROKEN:
749  return -1;
750  }
752 
753  if (!ENV_SMM)
755 
756  elog_debug("%s()\n", __func__);
757 
758  /* Set up the backing store */
759  if (elog_find_flash() < 0)
760  return -1;
761 
762  elog_size = region_device_sz(&elog_state.nv_dev);
763  mirror_buffer = elog_mirror_buf;
764  if (!mirror_buffer) {
765  printk(BIOS_ERR, "ELOG: Unable to allocate backing store\n");
766  return -1;
767  }
768  rdev_chain_mem_rw(&elog_state.mirror_dev, mirror_buffer, elog_size);
769 
770  /*
771  * Mark as initialized to allow elog_init() to be called and deemed
772  * successful in the prepare/shrink path which adds events.
773  */
775 
776  /* Load the log from flash and prepare the flash if necessary. */
777  if (elog_scan_flash() < 0 && elog_prepare_empty() < 0) {
778  printk(BIOS_ERR, "ELOG: Unable to prepare flash\n");
779  return -1;
780  }
781 
782  printk(BIOS_INFO, "ELOG: area is %zu bytes, full threshold %d,"
783  " shrink size %d\n", region_device_sz(&elog_state.nv_dev),
785 
786  if (ENV_PAYLOAD_LOADER)
788 
789  if (!ENV_SMM)
791 
792  return 0;
793 }
794 
795 /*
796  * Add an event to the log
797  */
798 int elog_add_event_raw(u8 event_type, void *data, u8 data_size)
799 {
800  struct event_header *event;
801  struct rtc_time time = { 0 };
802  u8 event_size;
803 
804  elog_debug("%s(type=%X)\n", __func__, event_type);
805 
806  /* Make sure ELOG structures are initialized */
807  if (elog_init() < 0)
808  return -1;
809 
810  /* Header + Data + Checksum */
811  event_size = sizeof(*event) + data_size + 1;
812  if (event_size > ELOG_MAX_EVENT_SIZE) {
813  printk(BIOS_ERR, "ELOG: Event(%X) data size too "
814  "big (%d)\n", event_type, event_size);
815  return -1;
816  }
817 
818  /* Make sure event data can fit */
819  event = elog_get_next_event_buffer(event_size);
820  if (event == NULL) {
821  printk(BIOS_ERR, "ELOG: Event(%X) does not fit\n",
822  event_type);
823  return -1;
824  }
825 
826  /* Fill out event data */
827  event->type = event_type;
828  event->length = event_size;
829  if (CONFIG(RTC))
830  rtc_get(&time);
831 
832  elog_fill_timestamp(event, time.sec, time.min, time.hour,
833  time.mday, time.mon, time.year);
834 
835  if (data_size)
836  memcpy(&event[1], data, data_size);
837 
838  /* Zero the checksum byte and then compute checksum */
839  elog_update_checksum(event, 0);
840  elog_update_checksum(event, -(elog_checksum_event(event)));
841  elog_put_event_buffer(event);
842 
844 
845  printk(BIOS_INFO, "ELOG: Event(%X) added with size %d ",
846  event_type, event_size);
847  if (event->day != 0) {
848  printk(BIOS_INFO, "at 20%02x-%02x-%02x %02x:%02x:%02x UTC\n",
849  event->year, event->month, event->day,
850  event->hour, event->minute, event->second);
851  } else {
852  printk(BIOS_INFO, "(timestamp unavailable)\n");
853  }
854 
855  /* Shrink the log if we are getting too full */
856  if (elog_shrink() < 0)
857  return -1;
858 
859  /* Ensure the updates hit the non-volatile storage. */
860  return elog_sync_to_nv();
861 }
862 
863 int elog_add_event(u8 event_type)
864 {
865  return elog_add_event_raw(event_type, NULL, 0);
866 }
867 
868 int elog_add_event_byte(u8 event_type, u8 data)
869 {
870  return elog_add_event_raw(event_type, &data, sizeof(data));
871 }
872 
873 int elog_add_event_word(u8 event_type, u16 data)
874 {
875  return elog_add_event_raw(event_type, &data, sizeof(data));
876 }
877 
878 int elog_add_event_dword(u8 event_type, u32 data)
879 {
880  return elog_add_event_raw(event_type, &data, sizeof(data));
881 }
882 
883 int elog_add_event_wake(u8 source, u32 instance)
884 {
885  struct elog_event_data_wake wake = {
886  .source = source,
887  .instance = instance
888  };
889  return elog_add_event_raw(ELOG_TYPE_WAKE_SOURCE, &wake, sizeof(wake));
890 }
891 
893 {
894  struct elog_event_extended_event event = {
895  .event_type = type,
896  .event_complement = complement
897  };
899  &event,
900  sizeof(event));
901 }
902 
903 /* Make sure elog_init() runs at least once to log System Boot event. */
904 static void elog_bs_init(void *unused) { elog_init(); }
struct arm64_kernel_header header
Definition: fit_payload.c:30
static int acpi_is_wakeup_s3(void)
Definition: acpi.h:9
const struct region_device * boot_device_ro(void)
Definition: rom_media.c:9
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void * memmove(void *dest, const void *src, size_t n)
Definition: memmove.c:10
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
void * smbios_carve_table(unsigned long start, u8 type, u8 length, u16 handle)
Definition: smbios.c:91
int smbios_full_table_len(struct smbios_header *header, u8 *str_table_start)
Definition: smbios.c:86
int rtc_get(struct rtc_time *time)
Definition: as3722rtc.c:62
u32 boot_count_read(void)
Definition: boot_count.c:96
@ BS_POST_DEVICE
Definition: bootstate.h:84
@ BS_ON_ENTRY
Definition: bootstate.h:95
#define offsetof(TYPE, MEMBER)
Definition: helpers.h:84
#define MIN(a, b)
Definition: helpers.h:37
#define KiB
Definition: helpers.h:75
@ CB_SUCCESS
Call completed successfully.
Definition: cb_err.h:16
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
#define CBMEM_ID_ELOG
Definition: cbmem_id.h:23
enum cb_err elog_verify_header(const struct elog_header *header)
Definition: elog.c:11
void 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)
Definition: elog.c:52
void elog_update_checksum(struct event_header *event, uint8_t checksum)
Definition: elog.c:74
uint8_t elog_checksum_event(const struct event_header *event)
Definition: elog.c:80
#define ELOG_TYPE_LOG_CLEAR
Definition: elog.h:66
#define ELOG_TYPE_LAST_POST_CODE
Definition: elog.h:239
#define ELOG_MAX_EVENT_SIZE
Definition: elog.h:319
#define ELOG_TYPE_BOOT
Definition: elog.h:67
#define ELOG_RW_REGION_NAME
Definition: elog.h:21
#define ELOG_TYPE_EOL
Definition: elog.h:39
#define ELOG_SIGNATURE
Definition: elog.h:19
#define ELOG_HEADER_TYPE_OEM
Definition: elog.h:36
#define ELOG_TYPE_WAKE_SOURCE
Definition: elog.h:150
#define ELOG_TYPE_EXTENDED_EVENT
Definition: elog.h:296
#define ELOG_TYPE_POST_EXTRA
Definition: elog.h:240
#define ELOG_VERSION
Definition: elog.h:20
#define printk(level,...)
Definition: stdlib.h:16
static void elog_write_header_in_mirror(void)
Definition: elog.c:397
#define ELOG_SIZE
Definition: elog.c:58
int elog_add_event_word(u8 event_type, u16 data)
Definition: elog.c:873
static void elog_tandem_increment_last_write(size_t size)
Definition: elog.c:157
#define ELOG_SHRINK_PERCENTAGE
Definition: elog.c:22
static void elog_add_boot_count(void)
Definition: elog.c:727
BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, elog_bs_init, NULL)
static size_t elog_events_total_space(void)
Definition: elog.c:72
static int elog_prepare_empty(void)
Definition: elog.c:525
static void elog_debug_dump_buffer(const char *msg)
Definition: elog.c:163
static struct region_device * mirror_dev_get(void)
Definition: elog.c:61
static u8 * elog_flash_offset_to_address(void)
Definition: elog.c:541
static void log_last_boot_post(void)
Definition: elog.c:706
static void elog_move_events_to_front(size_t offset, size_t size)
Definition: elog.c:413
static int elog_find_flash(void)
Definition: elog.c:614
int elog_add_event_raw(u8 event_type, void *data, u8 data_size)
Definition: elog.c:798
static struct event_header * elog_get_event_buffer(size_t offset, size_t size)
Definition: elog.c:77
static bool elog_do_add_boot_count(void)
Definition: elog.c:697
elog_init_state
Definition: elog.c:31
@ ELOG_BROKEN
Definition: elog.c:34
@ ELOG_INITIALIZED
Definition: elog.c:33
@ ELOG_UNINITIALIZED
Definition: elog.c:32
static void elog_bs_init(void *unused)
Definition: elog.c:904
static int elog_scan_flash(void)
Definition: elog.c:359
static int elog_sync_to_nv(void)
Definition: elog.c:652
int elog_add_event_dword(u8 event_type, u32 data)
Definition: elog.c:878
int elog_init(void)
Definition: elog.c:739
int elog_add_event_byte(u8 event_type, u8 data)
Definition: elog.c:868
static uint8_t elog_mirror_buf[ELOG_SIZE]
Definition: elog.c:59
static size_t elog_is_event_valid(size_t offset)
Definition: elog.c:234
static int elog_shrink_by_size(size_t requested_size)
Definition: elog.c:497
static void elog_nv_erase(void)
Definition: elog.c:300
int elog_smbios_write_type15(unsigned long *current, int handle)
Definition: elog.c:560
static bool elog_nv_needs_update(void)
Definition: elog.c:135
static void elog_put_event_buffer(struct event_header *event)
Definition: elog.c:89
static void elog_nv_increment_last_write(size_t size)
Definition: elog.c:113
static size_t elog_events_start(void)
Definition: elog.c:66
static void elog_nv_write(size_t offset, size_t size)
Definition: elog.c:273
int elog_clear(void)
Definition: elog.c:603
#define NV_NEEDS_ERASE
Definition: elog.c:30
static void elog_nv_reset_last_write(void)
Definition: elog.c:108
static struct event_header * elog_get_next_event_buffer(size_t size)
Definition: elog.c:82
#define ELOG_MIN_AVAILABLE_ENTRIES
Definition: elog.c:21
static size_t elog_nv_region_to_update(size_t *offset)
Definition: elog.c:140
static bool elog_nv_needs_erase(void)
Definition: elog.c:130
int elog_add_event_wake(u8 source, u32 instance)
Definition: elog.c:883
static bool elog_should_shrink(void)
Definition: elog.c:125
#define elog_debug(STR...)
Definition: elog.c:27
static int elog_shrink(void)
Definition: elog.c:531
static void elog_tandem_reset_last_write(void)
Definition: elog.c:151
static size_t elog_mirror_reset_last_write(void)
Definition: elog.c:94
static int elog_update_event_buffer_state(void)
Definition: elog.c:313
static int elog_is_buffer_clear(size_t offset)
Definition: elog.c:189
static void elog_mirror_increment_last_write(size_t size)
Definition: elog.c:103
static size_t elog_do_shrink(size_t requested_size, size_t last_write)
Definition: elog.c:448
static int elog_is_header_valid(void)
Definition: elog.c:216
static void elog_nv_needs_possible_erase(void)
Definition: elog.c:118
int elog_add_extended_event(u8 type, u32 complement)
Definition: elog.c:892
int elog_add_event(u8 event_type)
Definition: elog.c:863
int cmos_post_previous_boot(u8 *code, u32 *extra)
Definition: post.c:40
@ CONFIG
Definition: dsi_common.h:201
static struct region_device rdev
Definition: flashconsole.c:14
static size_t offset
Definition: flashconsole.c:16
int fmap_locate_area_as_rdev_rw(const char *name, struct region_device *area)
Definition: fmap.c:154
uint64_t length
Definition: fw_cfg_if.h:1
uint64_t address
Definition: fw_cfg_if.h:0
@ SMBIOS_EVENT_LOG
Definition: smbios.h:248
@ SMBIOS_EVENTLOG_ACCESS_METHOD_MMIO32
Definition: smbios.h:837
@ SMBIOS_EVENTLOG_STATUS_VALID
Definition: smbios.h:842
static uint8_t checksum(uint8_t *data, int offset)
Definition: ipmi_fru.c:70
unsigned int type
Definition: edid.c:57
void timestamp_add_now(enum timestamp_id id)
Definition: timestamp.c:141
void hexdump(const void *memory, size_t length)
Definition: hexdump.c:7
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
u8 buffer[C2P_BUFFER_MAXSIZE]
Definition: psp_smm.c:18
ssize_t rdev_eraseat(const struct region_device *rd, size_t offset, size_t size)
Definition: region.c:114
int rdev_munmap(const struct region_device *rd, void *mapping)
Definition: region.c:65
static size_t region_device_sz(const struct region_device *rdev)
Definition: region.h:132
ssize_t rdev_writeat(const struct region_device *rd, const void *b, size_t offset, size_t size)
Definition: region.c:94
static void * rdev_mmap_full(const struct region_device *rd)
Definition: region.h:148
void * rdev_mmap(const struct region_device *rd, size_t offset, size_t size)
Definition: region.c:46
int rdev_chain_mem_rw(struct region_device *child, void *base, size_t size)
Definition: region.c:298
int rdev_chain(struct region_device *child, const struct region_device *parent, size_t offset, size_t size)
Definition: region.c:136
ssize_t rdev_readat(const struct region_device *rd, void *b, size_t offset, size_t size)
Definition: region.c:77
static size_t region_device_offset(const struct region_device *rdev)
Definition: region.h:137
#define ENV_PAYLOAD_LOADER
Definition: rules.h:260
#define ENV_SMM
Definition: rules.h:151
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
unsigned char uint8_t
Definition: stdint.h:8
uint32_t instance
Definition: elog.h:203
uint8_t source
Definition: elog.h:202
uint8_t reserved[2]
Definition: elog.h:15
u16 shrink_size
Definition: elog.c:39
struct region_device nv_dev
Definition: elog.c:49
enum elog_init_state elog_initialized
Definition: elog.c:53
size_t nv_last_write
Definition: elog.c:47
u16 full_threshold
Definition: elog.c:38
size_t mirror_last_write
Definition: elog.c:46
struct region_device mirror_dev
Definition: elog.c:51
uint8_t year
Definition: elog.h:27
uint8_t minute
Definition: elog.h:31
uint8_t month
Definition: elog.h:28
uint8_t hour
Definition: elog.h:30
uint8_t day
Definition: elog.h:29
uint8_t second
Definition: elog.h:32
Definition: rtc.h:6
int year
Definition: rtc.h:12
int hour
Definition: rtc.h:9
int mon
Definition: rtc.h:11
int min
Definition: rtc.h:8
int sec
Definition: rtc.h:7
int mday
Definition: rtc.h:10
u8 eos[2]
Definition: smbios.h:830
u8 log_type_descriptor_length
Definition: smbios.h:829
u16 data_offset
Definition: smbios.h:822
u8 header_format
Definition: smbios.h:827
u32 address
Definition: smbios.h:826
struct smbios_header header
Definition: smbios.h:819
u8 access_method
Definition: smbios.h:823
u8 log_status
Definition: smbios.h:824
u16 header_offset
Definition: smbios.h:821
u32 change_token
Definition: smbios.h:825
u16 area_length
Definition: smbios.h:820
u8 log_type_descriptors
Definition: smbios.h:828
@ TS_ELOG_INIT_START
@ TS_ELOG_INIT_END