summaryrefslogtreecommitdiff
path: root/src/mainboard
diff options
context:
space:
mode:
authorWerner Zeh <werner.zeh@siemens.com>2017-09-12 08:58:44 +0200
committerWerner Zeh <werner.zeh@siemens.com>2017-09-14 18:12:49 +0000
commitefd0eb35af5e5620331d885d3140c734a6fc9098 (patch)
tree7f0a588f79ef3b2da7ac607e56bc88bf68edc6ed /src/mainboard
parent35cceb861c90083ea5dd6ad084141280d905aa36 (diff)
siemens/mc_apl1: Add delay to wait for legacy devices
There are old legacy onboard devices which are too slow for a coreboot boot with log level BIOS_ERR. In this case coreboot is so fast that these devices do not have enough time to become visible on the PCI bus and this in turn leads to missing resource allocation for this devices. The most generic way to work around this problem on existing hardware is to introduce a delay right before the PCI enumeration starts. The needed delay time depends on the hardware and will therefore be get from hwinfo. Change-Id: Ia91babc81e3a347bbc498c3def97b2ea70e10922 Signed-off-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-on: https://review.coreboot.org/21518 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Mario Scheithauer <mario.scheithauer@siemens.com>
Diffstat (limited to 'src/mainboard')
-rw-r--r--src/mainboard/siemens/mc_apl1/mainboard.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/mainboard/siemens/mc_apl1/mainboard.c b/src/mainboard/siemens/mc_apl1/mainboard.c
index d8374fc2a4..fb849f9872 100644
--- a/src/mainboard/siemens/mc_apl1/mainboard.c
+++ b/src/mainboard/siemens/mc_apl1/mainboard.c
@@ -23,6 +23,9 @@
#include <intelblocks/lpc_lib.h>
#include <soc/pci_devs.h>
#include <string.h>
+#include <bootstate.h>
+#include <timer.h>
+#include <timestamp.h>
#include "brd_gpio.h"
#include "ptn3460.h"
@@ -141,6 +144,34 @@ static void mainboard_final(void *chip_info)
}
}
+static void wait_for_legacy_dev(void *unused)
+{
+ uint32_t legacy_delay, us_since_boot;
+ struct stopwatch sw;
+
+ /* Open main hwinfo block. */
+ if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
+ return;
+
+ /* Get legacy delay parameter from hwinfo. */
+ if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
+ sizeof(legacy_delay)) != sizeof(legacy_delay))
+ return;
+
+ us_since_boot = get_us_since_boot();
+ /* No need to wait if the time since boot is already long enough.*/
+ if (us_since_boot > legacy_delay)
+ return;
+ stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
+ printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
+ legacy_delay - us_since_boot, legacy_delay);
+ while (!stopwatch_expired(&sw))
+ ;
+ printk(BIOS_NOTICE, "done!\n");
+}
+
+BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, wait_for_legacy_dev, NULL);
+
struct chip_operations mainboard_ops = {
.init = mainboard_init,
.final = mainboard_final,