blob: 8e56b852421f998da7f1fdfce2ad410ac2ec1c34 [file] [log] [blame]
Duncan Laurie7d2b81c2012-06-23 16:08:47 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
18 */
19
20#include <arch/acpi.h>
21#include <console/console.h>
22#include <pc80/mc146818rtc.h>
23#include <spi.h>
24#include <spi_flash.h>
25#include <stdint.h>
26#include <string.h>
27#include <elog.h>
28#include "elog_internal.h"
29
30#if CONFIG_ELOG_FLASH_BASE == 0
31#error "CONFIG_ELOG_FLASH_BASE is invalid"
32#endif
33#if CONFIG_ELOG_FULL_THRESHOLD >= CONFIG_ELOG_AREA_SIZE
34#error "CONFIG_ELOG_FULL_THRESHOLD is larger than CONFIG_ELOG_AREA_SIZE"
35#endif
36#if (CONFIG_ELOG_AREA_SIZE - CONFIG_ELOG_FULL_THRESHOLD) < (MAX_EVENT_SIZE + 1)
37#error "CONFIG_ELOG_FULL_THRESHOLD is too small"
38#endif
39#if CONFIG_ELOG_SHRINK_SIZE >= CONFIG_ELOG_AREA_SIZE
40#error "CONFIG_ELOG_SHRINK_SIZE is larger than CONFIG_ELOG_AREA_SIZE"
41#endif
42#if (CONFIG_ELOG_AREA_SIZE - CONFIG_ELOG_SHRINK_SIZE) > \
43 CONFIG_ELOG_FULL_THRESHOLD
44#error "CONFIG_ELOG_SHRINK_SIZE is too large"
45#endif
46
47#if CONFIG_ELOG_DEBUG
48#define elog_debug(STR...) printk(BIOS_DEBUG, STR)
49#else
50#define elog_debug(STR...)
51#endif
52
53/*
54 * Static variables for ELOG state
55 */
56static int elog_initialized;
57static struct spi_flash *elog_spi;
58static struct elog_descriptor elog_flash_area;
59static struct elog_descriptor elog_mem_area;
60
61static inline struct elog_descriptor* elog_get_mem(void)
62{
63 return &elog_mem_area;
64}
65
66static inline struct elog_descriptor* elog_get_flash(void)
67{
68 return &elog_flash_area;
69}
70
71/*
72 * Convert a memory mapped flash address into a flash offset
73 */
74static inline u32 elog_flash_address_to_offset(u8 *address)
75{
76 if (!elog_spi)
77 return 0;
78 return (u32)address - ((u32)~0UL - elog_spi->size + 1);
79}
80
81/*
82 * Convert a flash offset into a memory mapped flash address
83 */
84static inline u8* elog_flash_offset_to_address(u32 offset)
85{
86 if (!elog_spi)
87 return NULL;
88 return (u8*)((u32)~0UL - elog_spi->size + 1 + offset);
89}
90
91/*
92 * The ELOG header is at the very beginning of the area
93 */
94static inline struct elog_header*
95elog_get_header(struct elog_descriptor *elog)
96{
97 return elog->backing_store;
98}
99
100/*
101 * Pointer to an event log header in the event data area
102 */
103static inline struct event_header*
104elog_get_event_base(struct elog_descriptor *elog, u32 offset)
105{
106 return (struct event_header *)&elog->data[offset];
107}
108
109/*
110 * Pointer to where the next event should be stored
111 */
112static inline struct event_header*
113elog_get_next_event_base(struct elog_descriptor *elog)
114{
115 return elog_get_event_base(elog, elog->next_event_offset);
116}
117
118/*
119 * Pointer to the last logged event
120 */
121static inline struct event_header*
122elog_get_last_event_base(struct elog_descriptor *elog)
123{
124 return elog_get_event_base(elog, elog->last_event_offset);
125}
126
127/*
128 * Update the checksum at the last byte
129 */
130static void elog_update_checksum(struct event_header *event, u8 checksum)
131{
132 u8 *event_data = (u8*)event;
133 event_data[event->length - 1] = checksum;
134}
135
136/*
137 * Simple byte checksum for events
138 */
139static u8 elog_checksum_event(struct event_header *event)
140{
141 u8 index, checksum = 0;
142 u8 *data = (u8*)event;
143
144 for (index = 0; index < event->length; index++)
145 checksum += data[index];
146 return checksum;
147}
148
149/*
150 * Check if a raw buffer is filled with ELOG_TYPE_EOL byte
151 */
152static int elog_is_buffer_clear(u8 *base, u32 size)
153{
154 u8 *current = base;
155 u8 *end = current + size;
156
157 elog_debug("elog_is_buffer_clear(base=0x%p size=%u)\n", base, size);
158
159 for (; current != end; current++) {
160 if (*current != ELOG_TYPE_EOL)
161 return 0;
162 }
163 return 1;
164}
165
166/*
167 * Verify whether ELOG area is filled with ELOG_TYPE_EOL byte
168 */
169static int elog_is_area_clear(struct elog_descriptor *elog)
170{
171 return elog_is_buffer_clear(elog->backing_store, elog->total_size);
172}
173
174/*
175 * Check that the ELOG area has been initialized and is valid.
176 */
177static int elog_is_area_valid(struct elog_descriptor *elog)
178{
179 elog_debug("elog_is_area_valid()\n");
180
181 if (elog->area_state != ELOG_AREA_HAS_CONTENT)
182 return 0;
183 if (elog->header_state != ELOG_HEADER_VALID)
184 return 0;
185 if (elog->event_buffer_state != ELOG_EVENT_BUFFER_OK)
186 return 0;
187 return 1;
188}
189
190/*
191 * Verify the contents of an ELOG Header structure
192 * Returns 1 if the header is valid, 0 otherwise
193 */
194static int elog_is_header_valid(struct elog_header *header)
195{
196 elog_debug("elog_is_header_valid()\n");
197
198 if (header->magic != ELOG_SIGNATURE) {
199 printk(BIOS_ERR, "ELOG: header magic 0x%X != 0x%X\n",
200 header->magic, ELOG_SIGNATURE);
201 return 0;
202 }
203 if (header->version != ELOG_VERSION) {
204 printk(BIOS_ERR, "ELOG: header version %u != %u\n",
205 header->version, ELOG_VERSION);
206 return 0;
207 }
208 if (header->header_size != sizeof(*header)) {
209 printk(BIOS_ERR, "ELOG: header size mismatch %u != %u\n",
210 header->header_size, sizeof(*header));
211 return 0;
212 }
213 return 1;
214}
215
216/*
217 * Validate the event header and data.
218 */
219static int elog_is_event_valid(struct elog_descriptor *elog, u32 offset)
220{
221 struct event_header *event;
222
223 event = elog_get_event_base(elog, offset);
224 if (!event)
225 return 0;
226
227 /* Validate event length */
228 if ((offsetof(struct event_header, type) +
229 sizeof(event->type) - 1 + offset) >= elog->data_size)
230 return 0;
231
232 /* End of event marker has been found */
233 if (event->type == ELOG_TYPE_EOL)
234 return 0;
235
236 /* Check if event fits in area */
237 if ((offsetof(struct event_header, length) +
238 sizeof(event->length) - 1 + offset) >= elog->data_size)
239 return 0;
240
241 /*
242 * If the current event length + the current offset exceeds
243 * the area size then the event area is corrupt.
244 */
245 if ((event->length + offset) >= elog->data_size)
246 return 0;
247
248 /* Event length must be at least header size + checksum */
249 if (event->length < (sizeof(*event) + 1))
250 return 0;
251
252 /* If event checksum is invalid the area is corrupt */
253 if (elog_checksum_event(event) != 0)
254 return 0;
255
256 /* Event is valid */
257 return 1;
258}
259
260/*
261 * Write 'size' bytes of data provided in 'buffer' into flash
262 * device at offset 'offset'. This will not erase the flash and
263 * it assumes the flash area is erased appropriately.
264 */
265static void elog_flash_write(u8 *address, u8 *buffer, u32 size)
266{
267 u32 offset;
268
269 if (!address || !buffer || !size || !elog_spi)
270 return;
271
272 offset = elog_flash_address_to_offset(address);
273
274 elog_debug("elog_flash_write(address=0x%p offset=0x%08x buffer=0x%p "
275 "size=%u)\n", address, offset, buffer, size);
276
277 /* Write the data to flash */
278 elog_spi->write(elog_spi, offset, size, buffer);
279}
280
281/*
282 * Erase the first block specified in the address.
283 * Only handles flash area within a single flash block.
284 */
285static void elog_flash_erase(u8 *address, u32 size)
286{
287 u32 offset;
288
289 if (!address || !size || !elog_spi)
290 return;
291
292 offset = elog_flash_address_to_offset(address);
293
294 elog_debug("elog_flash_erase(address=0x%p offset=0x%08x size=%u)\n",
295 address, offset, size);
296
297 /* Erase the sectors in this region */
298 elog_spi->erase(elog_spi, offset, size);
299}
300
301/*
302 * Scan the event area and validate each entry and
303 * update the ELOG descriptor state.
304 */
305static void elog_update_event_buffer_state(struct elog_descriptor *elog)
306{
307 u32 count = 0;
308 u32 offset = 0;
309 u32 last_offset = 0;
310 u32 last_event_size = 0;
311 struct event_header *event;
312
313 elog_debug("elog_update_event_buffer_state()\n");
314
315 /* Go through each event and validate it */
316 while (1) {
317 event = elog_get_event_base(elog, offset);
318
319 /* Do not de-reference anything past the area length */
320 if ((offsetof(struct event_header, type) +
321 sizeof(event->type) - 1 + offset) >= elog->data_size) {
322 elog->event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
323 break;
324 }
325
326 /* The end of the event marker has been found */
327 if (event->type == ELOG_TYPE_EOL)
328 break;
329
330 /* Validate the event */
331 if (!elog_is_event_valid(elog, offset)) {
332 elog->event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
333 break;
334 }
335
336 /* Move to the next event */
337 count++;
338 last_offset = offset;
339 last_event_size = event->length;
340 offset += event->length;
341 }
342
343 /* Ensure the remaining buffer is empty */
344 if (!elog_is_buffer_clear(&elog->data[offset],
345 elog->data_size - offset))
346 elog->event_buffer_state = ELOG_EVENT_BUFFER_CORRUPTED;
347
348 /* Update data into elog descriptor */
349 elog->event_count = count;
350 elog->next_event_offset = offset;
351 elog->last_event_offset = last_offset;
352 elog->last_event_size = last_event_size;
353}
354
355static void elog_validate_and_fill(struct elog_descriptor *elog)
356{
357 elog_debug("elog_validate_and_fill()\n");
358
359 /* Check if the area is empty or not */
360 if (elog_is_area_clear(elog)) {
361 elog->area_state = ELOG_AREA_EMPTY;
362 return;
363 }
364
365 elog->area_state = ELOG_AREA_HAS_CONTENT;
366
367 /* Validate the header */
368 if (!elog_is_header_valid(elog->staging_header)) {
369 elog->header_state = ELOG_HEADER_INVALID;
370 return;
371 }
372
373 elog->header_state = ELOG_HEADER_VALID;
374 elog_update_event_buffer_state(elog);
375}
376
377/*
378 * Initialize a new ELOG descriptor
379 */
380static void elog_init_descriptor(struct elog_descriptor *elog,
381 elog_descriptor_type type,
382 u8 *buffer, u32 size,
383 struct elog_header *header)
384{
385 elog_debug("elog_init_descriptor(type=%u buffer=0x%p size=%u)\n",
386 type, buffer, size);
387
388 elog->type = type;
389 elog->area_state = ELOG_AREA_UNDEFINED;
390 elog->header_state = ELOG_HEADER_INVALID;
391 elog->event_buffer_state = ELOG_EVENT_BUFFER_OK;
392 elog->backing_store = buffer;
393 elog->total_size = size;
394
395 /* Get staging header from backing store */
396 elog->staging_header = header;
397 memcpy(header, buffer, sizeof(struct elog_header));
398
399 /* Data starts immediately after header */
400 elog->data = &buffer[sizeof(struct elog_header)];
401 elog->data_size = size - sizeof(struct elog_header);
402
403 elog->next_event_offset = 0;
404 elog->last_event_offset = 0;
405 elog->last_event_size = 0;
406 elog->event_count = 0;
407
408 elog_validate_and_fill(elog);
409}
410
411/*
412 * Re-initialize an existing ELOG descriptor
413 */
414static void elog_reinit_descriptor(struct elog_descriptor *elog)
415{
416 elog_debug("elog_reinit_descriptor()\n");
417 elog_init_descriptor(elog, elog->type, elog->backing_store,
418 elog->total_size, elog->staging_header);
419}
420
421/*
422 * Create ELOG descriptor data structures for all ELOG areas.
423 */
424static int elog_setup_descriptors(u32 flash_base, u32 area_size)
425{
426 struct elog_header *staging_header;
427 u8 *area;
428
429 elog_debug("elog_setup_descriptors(base=0x%08x size=%u)\n",
430 flash_base, area_size);
431
432 /* Prepare flash descriptors */
433 if (flash_base == 0) {
434 printk(BIOS_ERR, "ELOG: Invalid flash base\n");
435 return -1;
436 }
437
438 staging_header = malloc(sizeof(struct elog_header));
439 if (!staging_header) {
440 printk(BIOS_ERR, "ELOG: Unable to allocate header\n");
441 return -1;
442 }
443
444 area = elog_flash_offset_to_address(flash_base);
445 if (!area) {
446 printk(BIOS_ERR, "ELOG: Unable to determine flash address\n");
447 return -1;
448 }
449 elog_init_descriptor(elog_get_flash(), ELOG_DESCRIPTOR_FLASH,
450 area, area_size, staging_header);
451
452 /* Initialize the memory area to look like a cleared flash area */
453 area = malloc(area_size);
454 if (!area) {
455 printk(BIOS_ERR, "ELOG: Unable to allocate mem area\n");
456 return -1;
457 }
458 memset(area, ELOG_TYPE_EOL, area_size);
459 elog_init_descriptor(elog_get_mem(), ELOG_DESCRIPTOR_MEMORY,
460 area, area_size, (struct elog_header *)area);
461
462 return 0;
463}
464
465static void elog_flash_erase_area(void)
466{
467 struct elog_descriptor *elog = elog_get_flash();
468
469 elog_debug("elog_flash_erase_area()\n");
470
471 elog_flash_erase(elog->backing_store, elog->total_size);
472 elog_reinit_descriptor(elog);
473}
474
475static void elog_prepare_empty(struct elog_descriptor *elog,
476 u8 *data, u32 data_size)
477{
478 struct elog_header *header;
479
480 elog_debug("elog_prepare_empty(%u bytes)\n", data_size);
481
482 if (!elog_is_area_clear(elog))
483 return;
484
485 /* Write out the header */
486 header = elog->staging_header;
487 header->magic = ELOG_SIGNATURE;
488 header->version = ELOG_VERSION;
489 header->header_size = sizeof(struct elog_header);
490 header->reserved[0] = ELOG_TYPE_EOL;
491 header->reserved[1] = ELOG_TYPE_EOL;
492 elog_flash_write(elog->backing_store, (u8*)header,
493 header->header_size);
494
495 /* Write out the data */
496 if (data)
497 elog_flash_write(elog->data, data, data_size);
498
499 elog_reinit_descriptor(elog);
500
501 /* Clear the log if corrupt */
502 if (!elog_is_area_valid(elog))
503 elog_flash_erase_area();
504}
505
506static int elog_sync_flash_to_mem(void)
507{
508 struct elog_descriptor *mem = elog_get_mem();
509 struct elog_descriptor *flash = elog_get_flash();
510
511 elog_debug("elog_sync_flash_to_mem()\n");
512
513 /* Fill with empty pattern first */
514 memset(mem->backing_store, ELOG_TYPE_EOL, mem->total_size);
515
516 /* Copy the header to memory */
517 memcpy(mem->backing_store, flash->backing_store,
518 sizeof(struct elog_header));
519
520 /* Copy the valid flash contents to memory */
521 memcpy(mem->data, flash->data, flash->next_event_offset);
522
523 elog_reinit_descriptor(mem);
524
525 return elog_is_area_valid(mem) ? 0 : -1;
526}
527
528static int elog_sync_mem_to_flash(void)
529{
530 struct elog_descriptor *mem = elog_get_mem();
531 struct elog_descriptor *flash = elog_get_flash();
532 u8 *src, *dest;
533 u32 size;
534
535 elog_debug("elog_sync_mem_to_flash()\n");
536
537 /*
538 * In the case of a BIOS flash the active area will be cleared.
539 * One can catch this case and log the proper shutdown event by
540 * checking if the active flash elog is empty. Note that if the
541 * header size changes we will have corrupted the flash area.
542 * However that will be corrected on the next boot.
543 */
544 if (elog_is_area_clear(flash)) {
545 elog_prepare_empty(flash,
546 (u8*)elog_get_last_event_base(mem),
547 mem->last_event_size);
548 elog_sync_flash_to_mem();
549 return 0;
550 }
551
552 /* Calculate the destination and source bases */
553 dest = (u8*)elog_get_next_event_base(flash);
554 src = (u8*)elog_get_event_base(mem, flash->next_event_offset);
555
556 /* Calculate how much data to sync */
557 size = mem->next_event_offset - flash->next_event_offset;
558
559 /* Write the log data */
560 elog_flash_write(dest, src, size);
561
562 /* Update descriptor */
563 flash->event_count = mem->event_count;
564 flash->next_event_offset = mem->next_event_offset;
565 flash->last_event_offset = mem->last_event_offset;
566 flash->last_event_size = mem->last_event_size;
567
568 return 0;
569}
570
571/*
572 * Called during ELOG entry handler to prepare state for flash.
573 */
574static int elog_flash_area_bootstrap(void)
575{
576 struct elog_descriptor *elog = elog_get_flash();
577
578 elog_debug("elog_flash_area_bootstrap()\n");
579
580 switch (elog->area_state) {
581 case ELOG_AREA_UNDEFINED:
582 printk(BIOS_ERR, "ELOG: flash area undefined\n");
583 return -1;
584
585 case ELOG_AREA_EMPTY:
586 /* Write a new header with no data */
587 elog_prepare_empty(elog, NULL, 0);
588 break;
589
590 case ELOG_AREA_HAS_CONTENT:
591 break;
592 }
593
594 if (elog->header_state == ELOG_HEADER_INVALID) {
595 /* If the header is invalid no events can be salvaged
596 * so erase the entire area. */
597 printk(BIOS_ERR, "ELOG: flash area header invalid\n");
598 elog_flash_erase_area();
599 elog_prepare_empty(elog, NULL, 0);
600 }
601
602 if (elog->event_buffer_state == ELOG_EVENT_BUFFER_CORRUPTED) {
603 /* Wipe the source flash area */
604 elog_flash_erase_area();
605 elog_prepare_empty(elog, elog_get_mem()->data,
606 elog_get_mem()->next_event_offset);
607 }
608
609 return 0;
610}
611
612/*
613 * Shrink the log, deleting old entries and moving the
614 * remining ones to the front of the log.
615 */
616static int elog_shrink(void)
617{
618 struct elog_descriptor *mem = elog_get_mem();
619 struct event_header *event;
620 u16 discard_count = 0;
621 u16 offset = 0;
622
623 elog_debug("elog_shrink()\n");
624
625 if (mem->next_event_offset < CONFIG_ELOG_SHRINK_SIZE)
626 return 0;
627
628 while (1) {
629 /* Next event has exceeded constraints */
630 if (offset > CONFIG_ELOG_SHRINK_SIZE)
631 break;
632
633 event = elog_get_event_base(mem, offset);
634
635 /* Reached the end of the area */
636 if (!event || event->type == ELOG_TYPE_EOL)
637 break;
638
639 offset += event->length;
640 discard_count++;
641 }
642
643 /* Erase flash area */
644 elog_flash_erase_area();
645
646 /* Write new flash area */
647 elog_prepare_empty(elog_get_flash(),
648 (u8*)elog_get_event_base(mem, offset),
649 mem->next_event_offset - offset);
650
651 /* Update memory area from flash */
652 if (elog_sync_flash_to_mem() < 0) {
653 printk(BIOS_ERR, "Unable to update memory area from flash\n");
654 return -1;
655 }
656
657 /* Add clear event */
658 elog_add_event_word(ELOG_TYPE_LOG_CLEAR, offset);
659
660 return 0;
661}
662
663/*
664 * Initialize the SPI bus and probe for a flash chip
665 */
666static int elog_spi_init(void)
667{
668 elog_debug("elog_spi_init()\n");
669
670 /* Prepare SPI subsystem */
671 spi_init();
672
673 /* Look for flash chip */
674 elog_spi = spi_flash_probe(0, 0, 0, 0);
675
676 return elog_spi ? 0 : -1;
677}
678
679/*
680 * Clear the entire event log
681 */
682int elog_clear(void)
683{
684 struct elog_descriptor *flash = elog_get_flash();
685
686 elog_debug("elog_clear()\n");
687
688 /* Erase flash area */
689 elog_flash_erase_area();
690
691 /* Prepare new empty area */
692 elog_prepare_empty(flash, NULL, 0);
693
694 /* Update memory area from flash */
695 if (elog_sync_flash_to_mem() < 0)
696 return -1;
697
698 /* Log the clear event */
699 elog_add_event_word(ELOG_TYPE_LOG_CLEAR, flash->total_size);
700
701 return 0;
702}
703
704/*
705 * Event log main entry point
706 */
707int elog_init(void)
708{
709 if (elog_initialized)
710 return 0;
711
712 elog_debug("elog_init()\n");
713
714 /* Find SPI flash chip for backing store */
715 if (elog_spi_init() < 0) {
716 printk(BIOS_ERR, "ELOG: Unable to find SPI flash\n");
717 return -1;
718 }
719
720 /* Setup descriptors for flash and memory areas */
721 if (elog_setup_descriptors(CONFIG_ELOG_FLASH_BASE,
722 CONFIG_ELOG_AREA_SIZE) < 0) {
723 printk(BIOS_ERR, "ELOG: Unable to initialize descriptors\n");
724 return -1;
725 }
726
727 /* Bootstrap the flash area */
728 if (elog_flash_area_bootstrap() < 0) {
729 printk(BIOS_ERR, "ELOG: Unable to bootstrap flash area\n");
730 return -1;
731 }
732
733 /* Initialize the memory area */
734 if (elog_sync_flash_to_mem() < 0) {
735 printk(BIOS_ERR, "ELOG: Unable to initialize memory area\n");
736 return -1;
737 }
738
739 elog_initialized = 1;
740
741 printk(BIOS_INFO, "ELOG: MEM @0x%p FLASH @0x%p\n",
742 elog_get_mem()->backing_store,
743 elog_get_flash()->backing_store);
744
745 printk(BIOS_INFO, "ELOG: areas are %d bytes, full threshold %d,"
746 " shrink size %d\n", CONFIG_ELOG_AREA_SIZE,
747 CONFIG_ELOG_FULL_THRESHOLD, CONFIG_ELOG_SHRINK_SIZE);
748
749 /* Log a clear event if necessary */
750 if (elog_get_flash()->event_count == 0)
751 elog_add_event_word(ELOG_TYPE_LOG_CLEAR,
752 elog_get_flash()->total_size);
753
754 return 0;
755}
756
757/*
758 * Populate timestamp in event header with current time
759 */
760static void elog_fill_timestamp(struct event_header *event)
761{
762 event->second = cmos_read(RTC_CLK_SECOND);
763 event->minute = cmos_read(RTC_CLK_MINUTE);
764 event->hour = cmos_read(RTC_CLK_HOUR);
765 event->day = cmos_read(RTC_CLK_DAYOFMONTH);
766 event->month = cmos_read(RTC_CLK_MONTH);
767 event->year = cmos_read(RTC_CLK_YEAR);
768
769 /* Basic sanity check of expected ranges */
770 if (event->month > 0x12 || event->day > 0x31 || event->hour > 0x23 ||
771 event->minute > 0x59 || event->second > 0x59) {
772 event->year = 0;
773 event->month = 0;
774 event->day = 0;
775 event->hour = 0;
776 event->minute = 0;
777 event->second = 0;
778 }
779}
780
781/*
782 * Add an event to the memory area
783 */
784static int elog_add_event_mem(u8 event_type, void *data, u8 data_size)
785{
786 struct event_header *event;
787 struct elog_descriptor *mem = elog_get_mem();
788 u8 event_size;
789
790 elog_debug("elog_add_event_mem(type=%X)\n", event_type);
791
792 /* Make sure ELOG structures are initialized */
793 if (elog_init() < 0)
794 return -1;
795
796 /* Header + Data + Checksum */
797 event_size = sizeof(*event) + data_size + 1;
798 if (event_size > MAX_EVENT_SIZE) {
799 printk(BIOS_ERR, "ELOG: Event(%X) data size too "
800 "big (%d)\n", event_type, event_size);
801 return -1;
802 }
803
804 /* Make sure event data can fit */
805 if ((mem->next_event_offset + event_size) >= mem->data_size) {
806 printk(BIOS_ERR, "ELOG: Event(%X) does not fit\n",
807 event_type);
808 return -1;
809 }
810
811 /* Fill out event data */
812 event = elog_get_next_event_base(mem);
813 event->type = event_type;
814 event->length = event_size;
815 elog_fill_timestamp(event);
816
817 if (data_size)
818 memcpy(&event[1], data, data_size);
819
820 /* Zero the checksum byte and then compute checksum */
821 elog_update_checksum(event, 0);
822 elog_update_checksum(event, -(elog_checksum_event(event)));
823
824 /* Update memory descriptor parameters */
825 mem->event_count++;
826 mem->last_event_offset = mem->next_event_offset;
827 mem->last_event_size = event_size;
828 mem->next_event_offset += event_size;
829
830 printk(BIOS_INFO, "ELOG: Event(%X) added with size %d\n",
831 event_type, event_size);
832 return 0;
833}
834
835void elog_add_event_raw(u8 event_type, void *data, u8 data_size)
836{
837 elog_debug("elog_add_event_raw(type=%X)\n", event_type);
838
839 /* Add event to the memory area */
840 if (elog_add_event_mem(event_type, data, data_size) < 0) {
841 printk(BIOS_ERR, "Unable to add event to memory area\n");
842 return;
843 }
844
845 /* Sync the memory buffer to flash */
846 elog_sync_mem_to_flash();
847
848 /* Shrink the log if we are getting too full */
849 if (elog_get_mem()->next_event_offset >= CONFIG_ELOG_FULL_THRESHOLD)
850 elog_shrink();
851}
852
853void elog_add_event(u8 event_type)
854{
855 elog_add_event_raw(event_type, NULL, 0);
856}
857
858void elog_add_event_byte(u8 event_type, u8 data)
859{
860 elog_add_event_raw(event_type, &data, sizeof(data));
861}
862
863void elog_add_event_word(u8 event_type, u16 data)
864{
865 elog_add_event_raw(event_type, &data, sizeof(data));
866}
867
868void elog_add_event_dword(u8 event_type, u32 data)
869{
870 elog_add_event_raw(event_type, &data, sizeof(data));
871}
872
873void elog_add_event_wake(u8 source, u32 instance)
874{
875 struct elog_event_data_wake wake = {
876 .source = source,
877 .instance = instance
878 };
879 elog_add_event_raw(ELOG_TYPE_WAKE_SOURCE, &wake, sizeof(wake));
880}