usbdebug: Fix reserve in CAR

We need sizeof(struct ehci_dbg_info) of 88 but only
reserved 64 bytes. If usbdebug_hw_init() was called
late in romstage, for some builds it would corrupt
CAR_GLOBALs like console_inited variable and stop
logging anything.

Also change pointer initialisation such that
glob_dbg_info will hit garbage collection for
PRE_RAM stages.

Change-Id: Ib49fca781e55619179aa8888e2d859560e050876
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/31174
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld
index 7b10f43..1b0d996 100644
--- a/src/arch/x86/car.ld
+++ b/src/arch/x86/car.ld
@@ -67,7 +67,8 @@
 	_car_drivers_storage_end = .;
 #endif
 	_car_ehci_dbg_info_start = .;
-        . += 64;
+	/* Reserve sizeof(struct ehci_dbg_info). */
+        . += 88;
         _car_ehci_dbg_info_end = .;
 	/* _car_global_start and _car_global_end provide symbols to per-stage
 	 * variables that are not shared like the timestamp and the pre-ram
diff --git a/src/arch/x86/include/arch/symbols.h b/src/arch/x86/include/arch/symbols.h
index 9ef6a3b..97a07c0 100644
--- a/src/arch/x86/include/arch/symbols.h
+++ b/src/arch/x86/include/arch/symbols.h
@@ -35,6 +35,9 @@
 #define _car_stack_size (_car_stack_end - _car_stack_start)
 
 extern char _car_ehci_dbg_info_start[];
+extern char _car_ehci_dbg_info_end[];
+#define _car_ehci_dbg_info_size \
+	(_car_ehci_dbg_info_end - _car_ehci_dbg_info_start)
 
 /*
  * The _car_relocatable_data_[start|end] symbols cover CAR data which is
diff --git a/src/drivers/usb/ehci_debug.c b/src/drivers/usb/ehci_debug.c
index 18d0491..c5fb984 100644
--- a/src/drivers/usb/ehci_debug.c
+++ b/src/drivers/usb/ehci_debug.c
@@ -66,13 +66,18 @@
 
 static inline struct ehci_debug_info *dbgp_ehci_info(void)
 {
-	if (IS_ENABLED(CONFIG_USBDEBUG_IN_PRE_RAM)
-	    && (ENV_ROMSTAGE || ENV_BOOTBLOCK || ENV_VERSTAGE))
-		glob_dbg_info_p =
-			(struct ehci_debug_info *)_car_ehci_dbg_info_start;
-	if (car_get_var(glob_dbg_info_p) == NULL)
-		car_set_var(glob_dbg_info_p, &glob_dbg_info);
-
+	if (car_get_var(glob_dbg_info_p) == NULL) {
+		struct ehci_debug_info *info;
+		if (ENV_BOOTBLOCK || ENV_VERSTAGE || ENV_ROMSTAGE) {
+			/* The message likely does not show if we hit this. */
+			if (sizeof(*info) > _car_ehci_dbg_info_size)
+				die("BUG: Increase ehci_dbg_info reserve in CAR");
+			info = (void *)_car_ehci_dbg_info_start;
+		} else {
+			info = &glob_dbg_info;
+		}
+		car_set_var(glob_dbg_info_p, info);
+	}
 	return car_get_var(glob_dbg_info_p);
 }