Nick: carldani E-mail: none Board: workaround broken delay functionality in recovery environmen Contents: Index: cli_classic.c =================================================================== --- cli_classic.c (Revision 1517) +++ cli_classic.c (Arbeitskopie) @@ -415,9 +415,6 @@ if (prog == PROGRAMMER_INVALID) prog = default_programmer; - /* FIXME: Delay calibration should happen in programmer code. */ - myusec_calibrate_delay(); - if (programmer_init(prog, pparam)) { fprintf(stderr, "Error: Programmer initialization failed.\n"); ret = 1; Index: flashrom.8 =================================================================== --- flashrom.8 (Revision 1517) +++ flashrom.8 (Arbeitskopie) @@ -226,6 +226,21 @@ programmers use a key/value interface in which the key and value is separated by an equal sign and different pairs are separated by a comma or a colon. .SS +.B Common parameters for all programmers +The initial delay loop calibration of flashrom usually takes more than one +second, and in case of a machine with high system load or variable CPU speed +flashrom may repeat the delay loop calibration a few times until it is satisfied +with the precision or until it gives up. You can speed up the delay loop +calibration using +.sp +.B " flashrom \-p programmername:delayloops=value" +.sp +where value is the number of loops per microsecond (Mloops per second) reported +during the last flashrom run in verbose mode. flashrom will use the specified +value as basis for the delay loop calibration, so do not worry if it is not the +exact value. You can expect an 1 GHz CPU to have delayloop values between 250 +and 2000. +.SS .BR "internal " programmer .TP .B Board Enables Index: flashrom.c =================================================================== --- flashrom.c (Revision 1517) +++ flashrom.c (Arbeitskopie) @@ -321,6 +321,10 @@ programmer_param = param; msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name); + + /* FIXME: Delay calibration should be programmer specific. */ + myusec_calibrate_delay(); + ret = programmer_table[programmer].init(); if (programmer_param && strlen(programmer_param)) { msg_perr("Unhandled programmer parameters: %s\n", Index: udelay.c =================================================================== --- udelay.c (Revision 1517) +++ udelay.c (Arbeitskopie) @@ -26,6 +26,7 @@ #include #include #include "flash.h" +#include "programmer.h" /* loops per microsecond */ static unsigned long micro = 1; @@ -39,6 +40,7 @@ } } +#if 0 static unsigned long measure_os_delay_resolution(void) { unsigned long timeusec; @@ -62,6 +64,7 @@ } return timeusec; } +#endif static unsigned long measure_delay(int usecs) { @@ -89,17 +92,34 @@ unsigned long count = 1000; unsigned long timeusec, resolution; int i, tries = 0; + char *delayloops; msg_pinfo("Calibrating delay loop... "); - resolution = measure_os_delay_resolution(); + //resolution = measure_os_delay_resolution(); + // Evil hack for broken environment. + resolution = 0; if (resolution) { msg_pdbg("OS timer resolution is %lu usecs, ", resolution); } else { msg_pinfo("OS timer resolution is unusable. "); } -recalibrate: + delayloops = extract_programmer_param("delayloops"); + if (delayloops) { + micro = strtoul(delayloops, NULL, 0); + free(delayloops); + if (micro == 0) { + /* The delay calibration function is void, we have to + * recover instead of throwing an error. + */ + micro = 1; + } + timeusec = measure_delay(1000); + } + +//recalibrate: count = 1000; +#if 0 while (1) { timeusec = measure_delay(count); if (timeusec > 1000000 / 4) @@ -111,7 +131,7 @@ count *= 2; } tries ++; - +#endif /* Avoid division by zero, but in that case the loop is shot anyway. */ if (!timeusec) timeusec = 1; @@ -120,6 +140,7 @@ micro = (count * micro) / timeusec + 1; msg_pdbg("%luM loops per second, ", micro); +#if 0 /* Did we try to recalibrate less than 5 times? */ if (tries < 5) { /* Recheck our timing to make sure we weren't just hitting @@ -146,13 +167,14 @@ if (timeusec < 90) { msg_pdbg("delay more than 10%% too short (got " "%lu%% of expected delay), " - "recalculating... ", timeusec); - goto recalibrate; + "not recalculating... ", timeusec); + //goto recalibrate; } } } else { msg_perr("delay loop is unreliable, trying to continue "); } +#endif /* We're interested in the actual precision. */ timeusec = measure_delay(10);