arch/x86,lib/thread: Enable thread support in romstage

This change does the following:
* Pushes the cpu_info struct into the top of the stack (just like
  c_start.S). This is required so the cpu_info function works correctly.

* Adds the thread.c to the romstage build.

I only enabled this for romstage since I haven't done any tests in other
stages, but in theory it should work for other stages.

BUG=b:179699789
TEST=Boot guybrush with threads enabled in romstage

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I8e32e1c54dea0d0c85dd6d6753147099aa54b9b5
Reviewed-on: https://review.coreboot.org/c/coreboot/+/56494
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc
index 3949e3a..e91ddac 100644
--- a/src/arch/x86/Makefile.inc
+++ b/src/arch/x86/Makefile.inc
@@ -154,6 +154,8 @@
 romstage-y += postcar_loader.c
 romstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
 romstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
+romstage-$(CONFIG_COOP_MULTITASKING) += thread.c
+romstage-$(CONFIG_COOP_MULTITASKING) += thread_switch.S
 
 romstage-srcs += $(wildcard $(src)/mainboard/$(MAINBOARDDIR)/romstage.c)
 romstage-libs ?=
diff --git a/src/arch/x86/assembly_entry.S b/src/arch/x86/assembly_entry.S
index 6e73027..b0e15dc 100644
--- a/src/arch/x86/assembly_entry.S
+++ b/src/arch/x86/assembly_entry.S
@@ -35,6 +35,14 @@
 	/* reset stack pointer to CAR/EARLYRAM stack */
 	mov	$_STACK_TOP, %esp
 
+#if CONFIG(COOP_MULTITASKING)
+	/* Push the thread pointer. */
+	push	$0
+#endif
+	/* Push the CPU index and struct CPU */
+	push	$0
+	push	$0
+
 	/* clear .bss section as it is not shared */
 	cld
 	xor	%eax, %eax
diff --git a/src/include/thread.h b/src/include/thread.h
index 3c06cc5..cb085b5 100644
--- a/src/include/thread.h
+++ b/src/include/thread.h
@@ -38,7 +38,7 @@
 /* Waits until the thread has terminated and returns the error code */
 enum cb_err thread_join(struct thread_handle *handle);
 
-#if ENV_RAMSTAGE && CONFIG(COOP_MULTITASKING)
+#if (ENV_RAMSTAGE || ENV_ROMSTAGE) && CONFIG(COOP_MULTITASKING)
 
 struct thread {
 	int id;
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index baf9c4d..bb3cf6a 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -149,8 +149,6 @@
 ramstage-y += edid.c
 ramstage-y += edid_fill_fb.c
 ramstage-y += memrange.c
-ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
-ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
 ramstage-$(CONFIG_GENERIC_GPIO_LIB) += gpio.c
 ramstage-$(CONFIG_GENERIC_UDELAY) += timer.c
 ramstage-y += b64_decode.c
@@ -160,6 +158,12 @@
 ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit.c
 ramstage-$(CONFIG_PAYLOAD_FIT_SUPPORT) += fit_payload.c
 
+romstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
+ramstage-$(CONFIG_TIMER_QUEUE) += timer_queue.c
+
+romstage-$(CONFIG_COOP_MULTITASKING) += thread.c
+ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
+
 romstage-y += cbmem_common.c
 romstage-y += imd_cbmem.c
 romstage-y += imd.c