blob: 4f2a87c93e843929f06530e3593b854cb5716945 [file] [log] [blame]
Stefan Reinauerabc0c852010-11-22 08:09:50 +00001/*
2 * This file is part of the coreboot project.
Stefan Reinauer5ff7c132011-10-31 12:56:45 -07003 *
Stefan Reinauerabc0c852010-11-22 08:09:50 +00004 * Copyright (C) 2003 Eric Biederman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22#include <arch/io.h>
Edward O'Callaghan0ae068e2014-06-21 21:42:25 +100023#include <elog.h>
Stefan Reinauerabc0c852010-11-22 08:09:50 +000024#include <console/console.h>
Edward O'Callaghan0ae068e2014-06-21 21:42:25 +100025#include <device/device.h>
Duncan Laurieb6e97b12012-09-09 19:09:56 -070026#include <pc80/mc146818rtc.h>
Duncan Lauriee807c342013-06-10 09:53:33 -070027#include <smp/spinlock.h>
Stefan Reinauerabc0c852010-11-22 08:09:50 +000028
29/* Write POST information */
30
Alexandru Gagniucf88204e2012-08-03 13:20:57 -050031/* someday romcc will be gone. */
32#ifndef __ROMCC__
33/* Some mainboards have very nice features beyond just a simple display.
34 * They can override this function.
35 */
36void __attribute__((weak)) mainboard_post(uint8_t value)
37{
38}
39
40#else
41/* This just keeps the number of #ifs to a minimum */
42#define mainboard_post(x)
43#endif
44
Duncan Laurieb6e97b12012-09-09 19:09:56 -070045#if CONFIG_CMOS_POST
Duncan Laurie1fc34612012-09-09 19:14:45 -070046
Duncan Lauriee807c342013-06-10 09:53:33 -070047DECLARE_SPIN_LOCK(cmos_post_lock)
48
Duncan Laurie1fc34612012-09-09 19:14:45 -070049#if !defined(__PRE_RAM__)
50void cmos_post_log(void)
51{
Duncan Lauriee807c342013-06-10 09:53:33 -070052 u8 code = 0;
Duncan Lauried5686fe2013-06-10 10:21:41 -070053#if CONFIG_CMOS_POST_EXTRA
54 u32 extra = 0;
55#endif
Duncan Lauriee807c342013-06-10 09:53:33 -070056
57 spin_lock(&cmos_post_lock);
Duncan Laurie1fc34612012-09-09 19:14:45 -070058
59 /* Get post code from other bank */
60 switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
61 case CMOS_POST_BANK_0_MAGIC:
62 code = cmos_read(CMOS_POST_BANK_1_OFFSET);
Duncan Lauried5686fe2013-06-10 10:21:41 -070063#if CONFIG_CMOS_POST_EXTRA
64 extra = cmos_read32(CMOS_POST_BANK_1_EXTRA);
65#endif
Duncan Laurie1fc34612012-09-09 19:14:45 -070066 break;
67 case CMOS_POST_BANK_1_MAGIC:
68 code = cmos_read(CMOS_POST_BANK_0_OFFSET);
Duncan Lauried5686fe2013-06-10 10:21:41 -070069#if CONFIG_CMOS_POST_EXTRA
70 extra = cmos_read32(CMOS_POST_BANK_0_EXTRA);
71#endif
Duncan Laurie1fc34612012-09-09 19:14:45 -070072 break;
Duncan Laurie1fc34612012-09-09 19:14:45 -070073 }
74
Duncan Lauriee807c342013-06-10 09:53:33 -070075 spin_unlock(&cmos_post_lock);
76
Duncan Laurie1fc34612012-09-09 19:14:45 -070077 /* Check last post code in previous boot against normal list */
78 switch (code) {
79 case POST_OS_BOOT:
80 case POST_OS_RESUME:
81 case POST_ENTER_ELF_BOOT:
82 case 0:
83 break;
84 default:
85 printk(BIOS_WARNING, "POST: Unexpected post code "
86 "in previous boot: 0x%02x\n", code);
87#if CONFIG_ELOG
88 elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code);
Duncan Lauried5686fe2013-06-10 10:21:41 -070089#if CONFIG_CMOS_POST_EXTRA
90 if (extra)
91 elog_add_event_dword(ELOG_TYPE_POST_EXTRA, extra);
92#endif
Duncan Laurie1fc34612012-09-09 19:14:45 -070093#endif
94 }
95}
Duncan Lauried5686fe2013-06-10 10:21:41 -070096
97#if CONFIG_CMOS_POST_EXTRA
98void post_log_extra(u32 value)
99{
100 spin_lock(&cmos_post_lock);
101
102 switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
103 case CMOS_POST_BANK_0_MAGIC:
104 cmos_write32(CMOS_POST_BANK_0_EXTRA, value);
105 break;
106 case CMOS_POST_BANK_1_MAGIC:
107 cmos_write32(CMOS_POST_BANK_1_EXTRA, value);
108 break;
109 }
110
111 spin_unlock(&cmos_post_lock);
112}
Duncan Laurie8adf7a22013-06-10 10:34:20 -0700113
114void post_log_path(struct device *dev)
115{
116 if (dev) {
117 /* Encode path into lower 3 bytes */
118 u32 path = dev_path_encode(dev);
119 /* Upper byte contains the log type */
120 path |= CMOS_POST_EXTRA_DEV_PATH << 24;
121 post_log_extra(path);
122 }
123}
124
125void post_log_clear(void)
126{
127 post_log_extra(0);
128}
Duncan Lauried5686fe2013-06-10 10:21:41 -0700129#endif /* CONFIG_CMOS_POST_EXTRA */
Duncan Laurie1fc34612012-09-09 19:14:45 -0700130#endif /* !__PRE_RAM__ */
131
Duncan Laurieb6e97b12012-09-09 19:09:56 -0700132static void cmos_post_code(u8 value)
133{
Duncan Lauriee807c342013-06-10 09:53:33 -0700134 spin_lock(&cmos_post_lock);
135
Duncan Laurieb6e97b12012-09-09 19:09:56 -0700136 switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
137 case CMOS_POST_BANK_0_MAGIC:
138 cmos_write(value, CMOS_POST_BANK_0_OFFSET);
139 break;
140 case CMOS_POST_BANK_1_MAGIC:
141 cmos_write(value, CMOS_POST_BANK_1_OFFSET);
142 break;
143 }
Duncan Lauriee807c342013-06-10 09:53:33 -0700144
145 spin_unlock(&cmos_post_lock);
Duncan Laurieb6e97b12012-09-09 19:09:56 -0700146}
147#endif /* CONFIG_CMOS_POST */
148
Stefan Reinauerabc0c852010-11-22 08:09:50 +0000149void post_code(uint8_t value)
150{
Stefan Reinauerd4814bd2011-04-21 20:45:45 +0000151#if !CONFIG_NO_POST
152#if CONFIG_CONSOLE_POST
Stefan Reinauerabc0c852010-11-22 08:09:50 +0000153 print_emerg("POST: 0x");
154 print_emerg_hex8(value);
155 print_emerg("\n");
156#endif
Duncan Laurieb6e97b12012-09-09 19:09:56 -0700157#if CONFIG_CMOS_POST
158 cmos_post_code(value);
159#endif
Idwer Vollering5809a732014-03-11 15:36:21 +0000160#if CONFIG_POST_IO
161 outb(value, CONFIG_POST_IO_PORT);
David Hendricks6b908d02012-11-05 12:34:09 -0800162#endif
Stefan Reinauerabc0c852010-11-22 08:09:50 +0000163#endif
Alexandru Gagniucf88204e2012-08-03 13:20:57 -0500164 mainboard_post(value);
Stefan Reinauerabc0c852010-11-22 08:09:50 +0000165}