blob: c5cd86ce85cadf58d263b3bda486f6054b177be4 [file] [log] [blame]
Nico Huber5ce0fe12017-07-25 16:11:36 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <stdint.h>
15#ifdef __ROMCC__
16#include <arch/cbfs.h>
17#else
18#include <cbfs.h>
19#endif
20#include <pc80/mc146818rtc.h>
21#if IS_ENABLED(CONFIG_USE_OPTION_TABLE)
22#include <option_table.h>
23#endif
24
25int cmos_error(void);
26int cmos_error(void)
27{
28 unsigned char reg_d;
29 /* See if the cmos error condition has been flagged */
30 reg_d = cmos_read(RTC_REG_D);
31 return (reg_d & RTC_VRT) == 0;
32}
33
34int cmos_chksum_valid(void);
35int cmos_chksum_valid(void)
36{
37#if IS_ENABLED(CONFIG_USE_OPTION_TABLE)
38 unsigned char addr;
39 u16 sum, old_sum;
40
41 sum = 0;
42 /* Compute the cmos checksum */
43 for (addr = LB_CKS_RANGE_START; addr <= LB_CKS_RANGE_END; addr++)
44 sum += cmos_read(addr);
45
46 /* Read the stored checksum */
47 old_sum = cmos_read(LB_CKS_LOC) << 8;
48 old_sum |= cmos_read(LB_CKS_LOC + 1);
49
50 return sum == old_sum;
51#else
52 return 0;
53#endif
54}
55
56#if IS_ENABLED(CONFIG_USE_OPTION_TABLE)
57void sanitize_cmos(void)
58{
59 if (cmos_error() || !cmos_chksum_valid() ||
60 IS_ENABLED(CONFIG_STATIC_OPTION_TABLE)) {
61 size_t length = 128;
62 const unsigned char *cmos_default =
63#ifdef __ROMCC__
64 walkcbfs("cmos.default");
65#else
66 cbfs_boot_map_with_leak("cmos.default",
67 CBFS_COMPONENT_CMOS_DEFAULT, &length);
68#endif
69 if (cmos_default) {
70 int i;
71 cmos_disable_rtc();
72 for (i = 14; i < MIN(128, length); i++)
73 cmos_write_inner(cmos_default[i], i);
74 cmos_enable_rtc();
75 }
76 }
77}
78#endif