aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2016-10-07 12:58:17 +0200
committerNico Huber <nico.h@gmx.de>2016-11-06 17:28:13 +0100
commite0ed9025cf7453212e5e5a845e34e0b7ecfa3eb9 (patch)
tree0e904b2c054723cae2760e8778998f0a93851f1c
parent85a80ef4726a0f088d7d2007553349b861908386 (diff)
Add option to use Ada code in ramstage
If selected, libgnat will be linked into ramstage. And, to support Ada package intializations, we have to call ramstage_adainit(). Change-Id: I11417db21f16bf3007739a097d63fd592344bce3 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/16944 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/Kconfig5
-rw-r--r--src/include/adainit.h35
-rw-r--r--src/lib/gnat/Makefile.inc4
-rw-r--r--src/lib/hardwaremain.c13
4 files changed, 57 insertions, 0 deletions
diff --git a/src/Kconfig b/src/Kconfig
index e337a1a580..d6af6ebacd 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -1243,3 +1243,8 @@ config CHECKLIST_DATA_FILE_LOCATION
symbols contained only in <stage>_complete.dat will be flagged as
required and not implemented if a weak implementation is found in the
resulting image.
+
+config RAMSTAGE_ADA
+ def_bool n
+ help
+ Selected by features that use Ada code in ramstage.
diff --git a/src/include/adainit.h b/src/include/adainit.h
new file mode 100644
index 0000000000..34f45cbf8e
--- /dev/null
+++ b/src/include/adainit.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef _ADAINIT_H
+#define _ADAINIT_H
+
+/**
+ * @file adainit.h
+ *
+ * Ada supports some complex constructs that result in code for runtime
+ * initialization. It's also possible to have explicit procedures for
+ * package level initialization (e.g. you can initialize huge arrays in
+ * a loop instead of cluttering the binary).
+ *
+ * When an Ada main() is in charge, GNAT emmits the call to the initia-
+ * lizations automatically. When not, we have to call it explicitly.
+ */
+
+#if IS_ENABLED(CONFIG_RAMSTAGE_ADA)
+void ramstage_adainit(void);
+#else
+static inline void ramstage_adainit(void) {}
+#endif
+
+#endif /* _ADAINIT_H */
diff --git a/src/lib/gnat/Makefile.inc b/src/lib/gnat/Makefile.inc
index 6ba274a7ef..394c838842 100644
--- a/src/lib/gnat/Makefile.inc
+++ b/src/lib/gnat/Makefile.inc
@@ -60,3 +60,7 @@ $(foreach arch,$(standard-archs), \
$(foreach arch,$(standard-archs), \
$(eval $(call libgnat-template,$(arch))))
+
+ifeq ($(CONFIG_RAMSTAGE_ADA),y)
+ramstage-libs += $$(obj)/libgnat-$(ARCH-ramstage-y)/libgnat.a
+endif
diff --git a/src/lib/hardwaremain.c b/src/lib/hardwaremain.c
index ab4d9f48e2..ef789601e6 100644
--- a/src/lib/hardwaremain.c
+++ b/src/lib/hardwaremain.c
@@ -18,6 +18,7 @@
* C Bootstrap code for the coreboot
*/
+#include <adainit.h>
#include <arch/exception.h>
#include <bootstate.h>
#include <console/console.h>
@@ -429,6 +430,18 @@ static void boot_state_schedule_static_entries(void)
void main(void)
{
+ /*
+ * We can generally jump between C and Ada code back and forth
+ * without trouble. But since we don't have an Ada main() we
+ * have to do some Ada package initializations that GNAT would
+ * do there. This has to be done before calling any Ada code.
+ *
+ * The package initializations should not have any dependen-
+ * cies on C code. So we can call them here early, and don't
+ * have to worry at which point we can start to use Ada.
+ */
+ ramstage_adainit();
+
/* TODO: Understand why this is here and move to arch/platform code. */
/* For MMIO UART this needs to be called before any other printk. */
if (IS_ENABLED(CONFIG_ARCH_X86))