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