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