summaryrefslogtreecommitdiff
path: root/src/drivers/pc80/rtc/post.c
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2020-01-03 12:23:52 +0200
committerNico Huber <nico.h@gmx.de>2020-01-10 15:30:34 +0000
commit0e557aba4eae472addb13becb9467090d2d2b793 (patch)
tree8ec750fbbeaa222fc385aea0c08bbfc7f154ec47 /src/drivers/pc80/rtc/post.c
parent94aaf5b4715b69e05a8bb19a470c86da5814ba9e (diff)
console/post: Move cmos_post_code() under pc80/rtc
We should keep console/ somewhat arch-agnostic. Change-Id: I4465888023ba5ae0706b5e98e541c40f975d11e3 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/38186 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/drivers/pc80/rtc/post.c')
-rw-r--r--src/drivers/pc80/rtc/post.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/drivers/pc80/rtc/post.c b/src/drivers/pc80/rtc/post.c
new file mode 100644
index 0000000000..e559edfd1c
--- /dev/null
+++ b/src/drivers/pc80/rtc/post.c
@@ -0,0 +1,143 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdint.h>
+#include <elog.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <pc80/mc146818rtc.h>
+#include <smp/spinlock.h>
+
+DECLARE_SPIN_LOCK(cmos_post_lock)
+
+void cmos_post_log(void)
+{
+ u8 code = 0;
+#if CONFIG(CMOS_POST_EXTRA)
+ u32 extra = 0;
+#endif
+
+ spin_lock(&cmos_post_lock);
+
+ /* Get post code from other bank */
+ switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
+ case CMOS_POST_BANK_0_MAGIC:
+ code = cmos_read(CMOS_POST_BANK_1_OFFSET);
+#if CONFIG(CMOS_POST_EXTRA)
+ extra = cmos_read32(CMOS_POST_BANK_1_EXTRA);
+#endif
+ break;
+ case CMOS_POST_BANK_1_MAGIC:
+ code = cmos_read(CMOS_POST_BANK_0_OFFSET);
+#if CONFIG(CMOS_POST_EXTRA)
+ extra = cmos_read32(CMOS_POST_BANK_0_EXTRA);
+#endif
+ break;
+ }
+
+ spin_unlock(&cmos_post_lock);
+
+ /* Check last post code in previous boot against normal list */
+ switch (code) {
+ case POST_OS_BOOT:
+ case POST_OS_RESUME:
+ case POST_ENTER_ELF_BOOT:
+ case 0:
+ break;
+ default:
+ printk(BIOS_WARNING, "POST: Unexpected post code "
+ "in previous boot: 0x%02x\n", code);
+#if CONFIG(ELOG) && (ENV_RAMSTAGE || CONFIG(ELOG_PRERAM))
+ elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code);
+#if CONFIG(CMOS_POST_EXTRA)
+ if (extra)
+ elog_add_event_dword(ELOG_TYPE_POST_EXTRA, extra);
+#endif
+#endif
+ }
+}
+
+void cmos_post_init(void)
+{
+ u8 magic = CMOS_POST_BANK_0_MAGIC;
+
+ /* Switch to the other bank */
+ switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
+ case CMOS_POST_BANK_1_MAGIC:
+ break;
+ case CMOS_POST_BANK_0_MAGIC:
+ magic = CMOS_POST_BANK_1_MAGIC;
+ break;
+ default:
+ /* Initialize to zero */
+ cmos_write(0, CMOS_POST_BANK_0_OFFSET);
+ cmos_write(0, CMOS_POST_BANK_1_OFFSET);
+#if CONFIG(CMOS_POST_EXTRA)
+ cmos_write32(0, CMOS_POST_BANK_0_EXTRA);
+ cmos_write32(0, CMOS_POST_BANK_1_EXTRA);
+#endif
+ }
+
+ cmos_write(magic, CMOS_POST_BANK_OFFSET);
+}
+
+#if CONFIG(CMOS_POST_EXTRA)
+void post_log_extra(u32 value)
+{
+ spin_lock(&cmos_post_lock);
+
+ switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
+ case CMOS_POST_BANK_0_MAGIC:
+ cmos_write32(value, CMOS_POST_BANK_0_EXTRA);
+ break;
+ case CMOS_POST_BANK_1_MAGIC:
+ cmos_write32(value, CMOS_POST_BANK_1_EXTRA);
+ break;
+ }
+
+ spin_unlock(&cmos_post_lock);
+}
+
+void post_log_path(const struct device *dev)
+{
+ if (dev) {
+ /* Encode path into lower 3 bytes */
+ u32 path = dev_path_encode(dev);
+ /* Upper byte contains the log type */
+ path |= CMOS_POST_EXTRA_DEV_PATH << 24;
+ post_log_extra(path);
+ }
+}
+
+void post_log_clear(void)
+{
+ post_log_extra(0);
+}
+#endif /* CONFIG_CMOS_POST_EXTRA */
+
+void cmos_post_code(u8 value)
+{
+ spin_lock(&cmos_post_lock);
+
+ switch (cmos_read(CMOS_POST_BANK_OFFSET)) {
+ case CMOS_POST_BANK_0_MAGIC:
+ cmos_write(value, CMOS_POST_BANK_0_OFFSET);
+ break;
+ case CMOS_POST_BANK_1_MAGIC:
+ cmos_write(value, CMOS_POST_BANK_1_OFFSET);
+ break;
+ }
+
+ spin_unlock(&cmos_post_lock);
+}