summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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))